(SpringBoot) 게시판 예제2
깃허브 repository : SpringBoot class practice
스프링 부트 예제
스프링 부트 프레임 워크로 넘어와서의 게시판 예제입니다.
@GetMapping("/main")
public String main(Model model){
model.addAttribute("list",service.boardList());
return"board/main";
}
그리고 이에 해당하는 main.html을 board파일 안에 만들어 줍니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<table class = "table table-hover">
<thead>
<tr>
<th>글번호</th>
<th>작성자</th>
<th>제 목</th>
<th>조회수</th>
</tr>
</thead>
<tr th:each="list: ${list}">
<td>[[${list.boardId}]]</td>
<td>[[${list.name}]]</td>
<td>[[${list.title}]]</td>
<td>[[${list.read}]]</td>
</tr>
</table>
</div>
</body>
</html>
제목을 클릭했을 때 상세보기 페이지로 넘어가는 작업을 해줍니다.
@GetMapping("/view")
public String view(Model model, int boardId){
model.addAttribute("view",service.getBoard(boardId));
return "board/view";
}
그리고 getBoard sql은 만들어 놨으니, 인터페이스와 서비스에 코드를 작성해줍니다.
Board getBoard(int boardId);
public Board getBoard(int boardId) {
return boardMapper.getBoard(boardId);
}
view.html도 작성해줍니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<p>글 번호: [[${view.boardId}]]</p>
<p>제 목: [[${view.title}]]</p>
<p>작성자: [[${view.name}]]</p>
내용: <textarea class="form-control" th:text="${view.content}"></textarea>
<p>조회수: [[${view.read}]]</p>
</div>
</body>
</html>
제목을 클릭했을때 view.html로 넘어가야하니 main.html에 a태그를 넣어서 수정해줍니다.
<td>[[${list.title}]]</td>
<td>
<a th:href="@{/board/view(boardId=${list.boardId})} ">
[[${list.title}]]
</a>
</td>
이제 게시글 등록기능을 추가해 줍니다. mapper, interface, service에 게시글 등록을 위한 코드를 작성해줍니다.
<insert id="uploadBoard" parameterType="com.example.springbootpractice.domain.Board">
insert into tbl_board (title, content, name) values (#{title}, #{content}, #{name});
</insert>
void uploadBoard(Board board);
public void uploadBoard(Board board){
boardMapper.uploadBoard(board);
}
업로드를 할때 form태그를 post방식으로 제출할 것이기 때문에 업로드 페이지 접속을 위한 get매퍼와 게시글 등록을 위한 post매퍼를 작성해 줍니다.
@GetMapping("/upload")
public String upload(Model model){
return "board/upload";
}
@PostMapping("/upload")
public String uploadBoard(Board board){
service.uploadBoard(board);
return "redirect:/board/main";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<form th:action="@{upload}" method="post">
이름: <input type="text" class="form-control" name="name">
제목: <input type="text" class="form-control" name="title">
내용: <textarea class="form-control" name="content"></textarea>
<button type="submit">등록</button>
</form>
</div>
</body>
</html>
아직 upload페이지에 접속하는 버튼을 안 만들었으니 직접 링크를 타고 들어가서 게시글이 잘 작성 되는지 테스트 해봅니다.
등록 버튼을 누르니 에러가 뜬다.
Connection이 read-only로 되어있어서 그렇다는 것 같다. read-only를 적용한것은 Service에 Transactional 어노테이션 밖에 없는것 같아서 Transactional(readOnly = false)로 바꿨다.
바꿔 줬더니 잘 등록 된다. 근데 다른 사람들은 readOnly = true 였어도 잘 되는데 무슨 문제인지 모르겠다.
남은 update와 delete기능을 구현한다. 위와 동일한 절차로 코드를 작성해준다.
<update id="updateBoard" parameterType="com.example.springbootpractice.domain.Board">
update tbl_board set title=#{title}, content=#{content} where boardId = #{boardId};
</update>
<delete id="deleteBoard" parameterType="int">
delete from tbl_board where boardId = #{boardId};
</delete>
void updateBoard(Board board);
void deleteBoard(int boardId);
public void updateBoard(Board board){
boardMapper.updateBoard(board);
}
public void deleteBoard(int boardId){
boardMapper.deleteBoard(boardId);
}
@PutMapping("/update")
public String updateBoard(Board board){
service.updateBoard(board);
return "redirect: /board/main";
}
@DeleteMapping("/delete")
public String deleteBoard(int boardId){
service.deleteBoard(boardId);
return "redirect: /board/main";
}
새로운 view단 페이지를 만들지 않고 view.html을 수정해서 만들어 줍니다.
<body>
<div class="container">
<p>글 번호: [[${view.boardId}]]</p>
<p>제 목: [[${view.title}]]</p>
<p>작성자: [[${view.name}]]</p>
<div id="content">
내용: <textarea class="form-control" th:text="${view.content}" readonly></textarea>
</div>
<p>조회수: [[${view.read}]]</p>
<button id="deleteBtn" class="btn btn-danger btn-sm float-left">삭제</button>
<button id="updateBtn" class="btn btn-info btn-sm float-right">수정</button>
<form id="form" th:action="@{/}" method="post">
</form>
</div>
추가로 스크립트문을 작성해주고 jquery스크립트를 임포트 해줍니다.
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="js/vendor/modernizr-3.8.0.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>window.jQuery || document.write('<script src="@{/js/vendor/jquery-3.4.1.min.js}"><\/script>')</script>
<script th:inline="javascript">
$(document).on('ready', function (e) {
var form = $("#form");
var boardId = [[${view.boardId}]];
$(document).on('click', '#deleteBtn', function (e) {
$('#form').attr("action", "delete");
form.append("<input type='hidden' name='boardId' value='"+boardId+"'>");
form.append("<input type='hidden' name='_method' value='delete'>");
form.submit();
});
$(document).on('click', '#updateBtn', function (e) {
var str = "<input class='form-control' width='250' placeholder='제목 입력' id='updateTitle'>";
$('#title').html(str);
str = "<textarea class='form-control' placeholder='내용 입력' id='updateContent'></textarea>";
$('#content').html(str);
$('#updateBtn').attr("id", "updateConfirmBtn");
});
$(document).on('click', '#updateConfirmBtn', function (e) {
$('#form').attr("action", "update");
var updateTitle = $('#updateTitle').val();
var updateContent = $('#updateContent').val();
form.append("<input type='hidden' name='boardId' value='"+boardId+"'>");
form.append("<input type='hidden' name='_method' value='put'>");
form.append("<input type='hidden' name='title' value='"+updateTitle+"'>");
form.append("<input type='hidden' name='content' value='"+updateContent+"'>");
form.submit();
});
});
</script>
스크립트 문을 작성할 때 큰따옴표와 작은따옴표를 잘 혼용해서 쓰는데 서로 어디서 닫히는지 잘 확인해야겠다. 자동으로 닫히기 때문에 이를 인지를 잘 못해서 오류가 빈번하게 발생한다.
게시글 예제는 여기까지