2022. 1. 19. 08:40ใSpring/[2022] Spring boot
๊ฒ์ํ์ ์ง๊ธ๊น์ง ๋ง์ด ๋ง๋ค์์๋๋ฐ ์คํ๋ง ๋ถํธ๋ฅผ ํ์ฉํด์ ๊ฒ์ํ์ ๋ง๋๋ ๊ฒ๋ ํ๋ฒ ํด๋ณด์ ํด์
๋ ๋ง๋ค์ด ๋ณธ๋ค!
1๏ธโฃ ํ ์ด๋ธ ์์ฑ
ํ ์ด๋ธ์ ์์ ๋ถํฐ ๊ณ์ ์ฌ์ฉํด์ค๋ ํ ์ด๋ธ์ ์ด์ฉํด์ค ์์ ์ด๋ค.
2๏ธโฃ ์์ฑ ํ๋ฉด
๊ธฐ๋ณธ ํ๋ฉด์ ์ด๋ ๊ฒ ๊ตฌ์ฑ๋์ด ์๋ค.
์ด๋ฒ์๋ ์ ๋ง ๊ฐ๋จํ๊ฒ CRUD๋ง ์์ฑํ ์์ ์ด๊ณ
์ด์ ๊ฒ์ฆ, ๋ก๊ทธ์ธ ๋ฑ์ ๊ตฌํํด์ ์ ์ ๋ฐ์ ์ํฌ ์์ ์ด๋ค.
(์ด๋ฒ์ ์ง์ง..!!!)
๋ช๋ฒ์ด๋ ๊ณต๋ถํ๋ฉด์ ๊ฒ์ํ์ ๋ง๋ค์ด์๋๋ฐ ๋ค๋ฅธ ์ ์ด๋ผ๋ฉด ํ์๋ฆฌํ๋ฅผ ํ์ฉํด JSP๋ ์ ํ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ ์ด๋ค!
์ฌ์ฉํด๋ณธ ๊ฒฐ๊ณผ HTML์ ๋ค๋ฅธ ์ฝ๋ ๋ฑ์ด ์์ด์ง ์๋๋ค๋ ์ ์ด ์ข๊ณ ํ์๋ฆฌํ๋ ์คํ๋ง์ ์ฐ๋์ฑ์ด ์ข์์ ํ์ฉํ๊ธฐ ๊ต์ฅํ ์ข์๋ค.
3๏ธโฃ Board.class
์ด๋ฒ์๋ ๋กฌ๋ณต๋ ํ์ฉํด์ ์ข ๋ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ํด์คฌ๋ค.
๋๋ฌด ์๋ ์๋ฃ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ณต๋ถํ๋ค ๋ณด๋๊น ์ด๊ฑธ ์ ๋ชฐ๋๋ค,,, ๋กฌ๋ณต,,
@Data
: @Getter, @Setter, @ToString, @EqualsAndHashCode์ @RequiredArgsConstructor๋ฅผ ํฉ์ณ๋์ ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ ๋ณดํต ์์ฑ์๋ ๋ณด์์?์ด๋ผ๊ณ ํ๋ ๋ฐ๋ก ๋ง๋ค์ด์ฃผ๋๊ฒ ๋ ์ข๋ค๊ณ ํด์ ์์ฑ์๋ ๋ฐ๋ก ๋ง๋ค์ด์คฌ๋ค.
4๏ธโฃ ๋ชฉ๋ก ์กฐํ
BoardController.class
์์ฒญ URL "/boards"๋ก HTTP ์์ฒญ ๋ฉ์๋๊ฐ GET์ด๋ฉด boards ํธ๋ค๋ฌ๊ฐ ์ํ๋๋ค.
@RequiredArgsConstructor
: ์ด ์ด๋ ธํ ์ด์ ์ ์ด๊ธฐํ๋์ง ์์ final ํ๋๋ , @NonNull์ด ๋ถ์ ํ๋์ ๋ํ ์์ฑ์๋ฅผ ์์ฑํด์ฃผ๋๋ฐ ์ฃผ๋ก ์์กด์ฑ ์ฃผ์ ์ ๋ํ ํธ์์ฑ์ ์ํด ์ฌ์ฉํ๋ค.
BoardService.class
BoardRepository.class
JdbcTemplateBoardRepository.class
์ด๋ฒ์๋ jdbcTemplate๋ฅผ ์ฌ์ฉํ๋๋ฐ ๋ค์์ myBatis, JPA๋ฅผ ์ฌ์ฉํด๋ณผ ์์ ์ด๋ค!
Boards.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container" style="max-width: 1000px">
<div class="py-5 text-center">
<h2 th:text="#{page.boards}">๊ธ ๋ชฉ๋ก</h2>
</div>
<div class="row">
<div class="col">
<button class="btn btn-primary float-end"
onclick="location.href='addForm.html'"
th:onclick="|location.href='@{/boards/add}'|"
type="button" th:text="#{page.addBoard}">๊ธ ๋ฑ๋ก</button>
</div>
</div>
<hr class="my-4">
<div>
<table class="table">
<thead>
<tr>
<th th:text="#{label.board.id}">ID</th>
<th th:text="#{label.board.subject}">์ ๋ชฉ</th>
<th th:text="#{label.board.name}">์์ฑ์</th>
<th th:text="#{label.board.viewcnt}">์กฐํ์</th>
<th th:text="#{label.board.regdate}">๋ฑ๋ก์ผ</th>
</tr>
</thead>
<tbody>
<tr th:each="board : ${boards}">
<td><a href="item.html" th:href="@{/boards/{uid}(uid=${board.uid})}" th:text="${board.uid}">๊ธ ID</a></td>
<td><a href="item.html" th:href="@{/boards/{uid}(uid=${board.uid})}" th:text="${board.subject}">์ ๋ชฉ</a></td>
<td th:text="${board.name}">์์ฑ์</td>
<td th:text="${board.viewcnt}">์กฐํ์</td>
<td th:text="${board.regdate}">๋ฑ๋ก์ผ</td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
ํ์ ๋ฆฌํ ๊ธฐ๋ณธ ๊ธฐ๋ฅ
th:text
-> HTML ์ฝํ ์ธ ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ ๋
th:text="${...}"
-> ${...} ๋ณ์ ํํ์
th:href="@{...}"
-> @{...} URL ๋งํฌ
th:each
-> ๋ฐ๋ณต
th:if, unless
-> ์กฐ๊ฑด (์ด๋ ํ์ ๋ฆฌํ๋ ํด๋น ์กฐ๊ฑด์ด ๋ง์ง ์์ผ๋ฉด ์์ ํ๊ทธ ์์ฒด๋ฅผ ๋ ๋๋งํ์ง ์๋๋ค!)
th:object
-> ์ปค๋ฉ๋ ๊ฐ์ฒด๋ฅผ ์ง์ ํ๋ค.
*{...}
-> ์ ํ ๋ณ์ ์์ผ๋ก th:object์์ ์ ํํ ๊ฐ์ฒด์ ์ ๊ทผํ๋ค.
th:field
-> HTML ํ๊ทธ์ id, value, name ๋ฑ ์์ฑ์ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ค๋ค.(๋ง์ ๊ธฐ๋ฅ ์ํํจ) โญโญ
ex) th:field="*{itemName}" = ${item.itemName}
5๏ธโฃ ๊ฒ์๊ธ ์กฐํ
BoardController.class
๊ฒ์๊ธ ์กฐํํ ๋๋ ์ฐ์ ์กฐํ์๋ ์ฆ๊ฐํด์ผํ๊ณ , ๊ธ ๋ชฉ๋ก๋ ์กฐํ๋์ด์ผ ํ๋ค.
์ด๋๋ /boards/{uid}๋ก ํด๋น ๊ฒ์๊ธ์ uid ๋ก ์กฐํํ๋ค.
BoardService.class
BoardRepository.class
JdbcTemplateBoardRepository.class
jdbcTemplate query()
: SELECT ์ฟผ๋ฆฌ ์คํ์ ์ํ ๋ฉ์๋
jdbcTemplate update()
: INSERT, UPDATE, DELETE ์ฟผ๋ฆฌ๋ update() ๋ฉ์๋๋ฅผ ์คํํ๋ค.
Board.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
<style>
.container {
max-width: 560px;
}
</style>
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2 th:text="#{page.board}">์ํ ์์ธ</h2>
</div>
<!-- ์ถ๊ฐ -->
<h2 th:if="${param.status}" th:text="'์ ์ฅ ์๋ฃ'"></h2>
<div>
<label for="boardId" th:text="#{label.board.id}">ID</label>
<input type="text" id="boardId" name="boardId" class="form-control" value="1" th:value="${board.uid}" readonly>
</div>
<div>
<label for="boardSubject" th:text="#{label.board.subject}">์ ๋ชฉ</label>
<input type="text" id="boardSubject" name="boardSubject" class="form-control" value="์ํA" th:value="${board.subject}" readonly>
</div>
<div>
<label for="name" th:text="#{label.board.name}">์์ฑ์</label>
<input type="text" id="name" name="name" class="form-control" value="์์ฑ์" th:value="${board.name}" readonly>
</div>
<div>
<label for="viewcnt" th:text="#{label.board.viewcnt}">์กฐํ์</label>
<input type="text" id="viewcnt" name="viewcnt" class="form-control" value="10" th:value="${board.viewcnt}" readonly>
</div>
<div>
<label for="regdate" th:text="#{label.board.regdate}">๋ฑ๋ก์ผ</label>
<input type="text" id="regdate" name="regdate" class="form-control" value="10" th:value="${board.regdate}" readonly>
</div>
<div>
<label for="contents" th:text="#{label.board.contents}">๊ธ ๋ด์ฉ</label>
<input type="text" id="contents" name="contents" class="form-control" value="10" th:value="${board.contents}" readonly>
</div>
<hr class="my-4">
<div class="row">
<div class="col">
<button class="w-100 btn btn-primary btn-lg"
onclick="location.href='editForm.html'"
th:onclick="|location.href='@{/boards/{uid}/edit(uid=${board.uid})}'|"
type="button" th:text="#{page.updateBoard}">์ํ ์์ </button>
</div>
<div class="col">
<button class="w-100 btn btn-secondary btn-lg"
onclick="location.href='items.html'"
th:onclick="|location.href='@{/boards}'|"
type="button" th:text="#{button.list}">๋ชฉ๋ก์ผ๋ก</button>
</div>
<div class="col">
<button class="w-100 btn btn-secondary btn-lg"
onclick="location.href='items.html'"
th:onclick="|location.href='@{/boards/{uid}/delete(uid=${board.uid})}'|"
type="button" th:text="#{button.delete}">์ญ์ </button>
</div>
</div>
</div> <!-- /container -->
</body>
</html>
6๏ธโฃ ๊ฒ์๊ธ ๋ฑ๋ก
BoardController.class
๋จผ์ @Getmapping("/add")์์๋ ๋ฑ๋ก ํผ์ ๋ณด์ฌ์ฃผ๊ณ , ๋ฑ๋ก ๋ฒํผ์ ๋๋ฅด๋ฉด @Postmaping์ผ๋ก ๊ฐ์ url๋ก ํด๋น ๊ธ์ ๋ฑ๋กํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ์ํ ๋ฑ๋กํ์๋ redirectํด์ ๋ชฉ๋ก ์กฐํํ๋ฉด์ผ๋ก ์ด๋ํ๋ค.
BoardService.class
BoardRepository.class
JdbcTemplateBoardRepository.class
addForm.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
<style>
.container {
max-width: 560px;
}
.field-error {
border-color: #dc3545;
color: #dc3545;
}
</style>
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2 th:text="#{page.addBoard}">์ํ ๋ฑ๋ก</h2>
</div>
<form action="item.html" th:action th:object="${board}" method="post">
<div>
<input type="hidden" id="name" class="form-control" th:field="*{name}" value="testUser" placeholder="์ ๋ชฉ์ ์
๋ ฅํ์ธ์.">
</div>
<div>
<label for="subject" th:text="#{label.board.subject}">์ ๋ชฉ</label>
<input type="text" id="subject" th:field="*{subject}" class="form-control" placeholder="์ ๋ชฉ์ ์
๋ ฅํ์ธ์.">
</div>
<div>
<label for="contents" th:text="#{label.board.contents}">๋ด์ฉ</label>
<textarea cols="150" rows="10" id="contents" th:field="*{contents}" class="form-control" placeholder="๋ด์ฉ์ ์
๋ ฅํ์ธ์.">
</textarea>
</div>
<hr class="my-4">
<div class="row">
<div class="col">
<button class="w-100 btn btn-primary btn-lg" type="submit" th:text="#{button.save}">์ ์ฅ</button>
</div>
<div class="col">
<button class="w-100 btn btn-secondary btn-lg"
onclick="location.href='items.html'"
th:onclick="|location.href='@{/boards}'|"
type="button" th:text="#{button.cancel}">์ทจ์</button>
</div>
</div>
</form>
</div> <!-- /container -->
</body>
</html>
7๏ธโฃ ๊ฒ์๊ธ ์ญ์
BoardController.class
์ฌ๊ธฐ์๋ ๋ฐ๋ก ํ๋ฉด ๊ตฌํ ์์ด ๊ฒ์๊ธ ์กฐํ ํ๋ฉด์์ ์ญ์ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ญ์ ๊ฐ ๋๋ฉด์ ๋ชฉ๋ก์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ค.
BoardService.class
BoardRepository.class
JdbcTemplateBoardRepository.class
8๏ธโฃ ๊ฒ์๊ธ ์์
BoardController.class
@GetMapping("/{uid}/edit") ์ ํตํด ํด๋น uid์ ๊ธ์ ๊ฐ์ ธ์ค๊ณ , ์์ ํ ์ ์๋ ํ์ด์ง๋ก ์ด๋ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ํ์ด์ง์์ ์์ ๋ฒํผ์ ๋๋ฅด๋ฉด @PostMapping("/{uid}/edit")์ผ๋ก ํด๋น ํธ๋ค๋ฌ๊ฐ ๋์ํ๊ณ ํ์ด์ง์ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ด ์์ ๋๋ค.
BoardService.class
BoardRepository.class
JdbcTemplateBoardRepository.class
์์ ํ ๋ค์์๋ ๊ฒ์๊ธ ์กฐํ ํ์ด์ง๋ก ์ด๋ํด์ ์์ ํ ๋ด์ฉ์ ํ์ธํ ์ ์๋ค.