목차
-
application.yml 그대로 복사해서 사용
-
src/main/resources => messages와css 폴더를 ch12프로젝트에 있는걸 복사해서 사용
-
kr.spring.board.vo => BoardVO
-
kr.spring.board.dao => BoardMapper
-
BoardMapper.xml 역시 ch12에서 복사해서 사용
-
kr.spring.board.service=>BoardService
-
BoardServiceImpl
-
kr.spring.board.controller => BoardController (ch12에서 그대로 복사)
-
templates => views => selectList.html
-
BoardController 내용수정
-
templates => views =>insertForm.html
-
BoardMapper.java 내용추가
-
BoardController.java 내용추가
-
templates => views =>selectDetail.html
application.yml 그대로 복사해서 사용
jsp를 사용하지 않고 HTML을 사용하기 때문에 코드 수정이 필요.
mvc:
view: #view 경로 및 확장자 지정
prefix: /WEB-INF/views/
suffix: .jsp
여기를 삭제하고 thymeleadf 설정을 넣는다.
thymeleaf:
prefix: classpath:templates/
suffix: .html
check-template-location: true
enabled: true
mode: HTML5
cache: false #캐시를 사용하지 않음. 새로고침하면 변경사항이 바로 확인
src/main/resources => messages와css 폴더를 ch12프로젝트에 있는걸 복사해서 사용
kr.spring.board.vo => BoardVO
package kr.spring.board.vo;
import java.sql.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
public class BoardVO {
private int num;
@NotBlank
private String writer;
@NotBlank
private String title;
@NotBlank
private String passwd;
@NotEmpty
private String content;
private Date reg_date;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
@Override
public String toString() {
return "BoardVO [num=" + num + ", writer=" + writer + ", title=" + title + ", passwd=" + passwd + ", content="
+ content + ", reg_date=" + reg_date + "]";
}
}
kr.spring.board.dao => BoardMapper
package kr.spring.board.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import kr.spring.board.vo.BoardVO;
@Mapper
public interface BoardMapper {
public void insertBoard(BoardVO board);
@Select("SELECT COUNT(*) FROM aboard")
public int getBoardCount();
public List<BoardVO> getBoardList(Map<String,Integer>map);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
BoardMapper.xml 역시 ch12에서 복사해서 사용
kr.spring.board.service=>BoardService
package kr.spring.board.service;
import java.util.List;
import java.util.Map;
import kr.spring.board.vo.BoardVO;
public interface BoardService {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(Map<String,Integer>map);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
BoardServiceImpl
package kr.spring.board.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import kr.spring.board.dao.BoardMapper;
import kr.spring.board.vo.BoardVO;
@Service
@Transactional
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardMapper boardMapper;
@Override
public void insertBoard(BoardVO board) {
boardMapper.insertBoard(board);
}
@Override
public int getBoardCount() {
return boardMapper.getBoardCount();
}
@Override
public List<BoardVO> getBoardList(Map<String, Integer> map) {
return boardMapper.getBoardList(map);
}
@Override
public BoardVO getBoard(int num) {
return boardMapper.getBoard(num);
}
@Override
public void updateBoard(BoardVO board) {
boardMapper.updateBoard(board);
}
@Override
public void deleteBoard(int num) {
boardMapper.deleteBoard(num);
}
}
kr.spring.board.controller => BoardController (ch12에서 그대로 복사)
templates => views => selectList.html
그냥만들면 webapp으로 가기 때문에 위치를 변경해줘야된다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>게시판목록</title>
<link rel="stylesheet" th:href="@{/css/style/css}" type="text/css"> <!-- th: 를 쓰면 thymeleaf의 속성으로 적용. -->
</head>
<body>
<div class="page-main">
<h2>게시판 목록</h2>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='insert.do'">
</div>
<!-- thymeleaf는 태그를 쓰지않고 속성을 쓴다고 생각하면된다. thymeleaf는 HTML하나만으로 view를 구현함. -->
<!-- 기존의 <c:if>대신 th:if를 사용. 만약 false이면(0이 아니면) 이 div가 나오지않음 -->
<div class="result-display" th:if="${count == 0}">표시할 내용이 없습니다.</div>
<div th:if="${count > 0}">
<table>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<tr th:each="board : ${list}">
<td th:text="${board.num}"></td>
<!-- @{detail.do?num=${board.num}}에서 detail앞에 /를 넣으면 url형태이다. 안쓰면 파일형태 -->
<!-- ? 대신에 ()소괄호로 감싸줘야된다. -->
<td><a th:href="@{detail.do(num=${board.num})}" th:text="${board.title}"></a></td>
<td th:text="${board.writer}"></td>
<td th:text="${board.reg_date}"></td>
</tr>
</table>
<div class="align-center" th:utext="${page}"></div>
</div>
</div>
</body>
</html>
BoardController 내용수정
views/를 넣어줌
89라인
//뷰 이름 설정
mav.setViewName("views/selectList");
//글쓰기 폼 호출
@GetMapping("/insert.do")
public String form() {
return "views/insertForm";
}
templates => views =>insertForm.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<link rel="stylesheet" th:href="@{/css/style.css}" type="text/css">
</head>
<body>
<div class="page-main">
<h2>글쓰기</h2>
<!-- th:object : request에 저장되어있는 자바빈 호출 -->
<form action="insert.do" method="post" th:object="${boardVO}">
<ul>
<li>
<label for="writer">작성자</label>
<!-- th:field : 자바빈에 필드 지정 (id와 클라이언트가 넣은 값value가 들어감)--> <!-- *{writer} 는 boardVO.writer라고 생각하면됨 -->
<input type="text" name="writer" th:field="*{writer}" th:errorclass="field-error">
<span th:errors="*{writer}" class="error-color"></span>
</li>
<li>
<label for="title">제목</label>
<input type="text" name="title" th:field="*{title}" th:errorclass="field-error">
<span th:errors="*{title}" class="error-color"></span>
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd" th:field="*{passwd}" th:errorclass="field-error">
<span th:errors="*{passwd}" class="error-color"></span>
</li>
<li>
<label for="content">내용</label>
<textarea th:field="*{content}" th:errorclass="field-error"></textarea>
<span th:errors="*{content}" class="error-color"></span>
</li>
</ul>
<div class="align-center">
<input type="submit" value="등록">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form>
</div>
</body>
</html>
BoardMapper.java 내용추가
@Select("SELECT * FROM aboard WHERE num=#{num}")
public BoardVO getBoard(int num);
BoardController.java 내용추가
views/ 추가
//글상세
@RequestMapping("/detail.do")
public ModelAndView detail(int num) {
BoardVO board =
boardService.getBoard(num);
return new ModelAndView("views/selectDetail","board",board);
}
templates => views =>selectDetail.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글상세</title>
<link rel="stylesheet" th:href="@{/css/style.css}" type="text/css">
</head>
<body>
<div class="page-main">
<h2 th:text="${board.title}"></h2>
<p>
<!-- 1,2번 방법중 어떤것을 써도 상관없음 -->
<span th:text="'글번호 :' + ${board.num}"></span><br><!-- 1번 방법 -->
<span>작성자 : [[${board.writer}]]</span><br><!-- 2번 방법 -->
<span>작성일 : [[${board.reg_date}]]</span>
</p>
<hr width="100%" size="1" noshade="noshade">
<p th:text="${board.content}"></p>
<div class="align-center">
<!-- th:onclick 을 쓸 떄는 ""안에 | 를 맨끝에 써줘야됨. 자바스크립트를 쓰기 위해 파이프(|)를 씀 -->
<input type="button" value="수정" th:onclick="|location.href='@{update.do(num=${board.num})}'|">
<input type="button" value="삭제" th:onclick="|location.href='@{delete.do(num=${board.num})}'|">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</div>
</body>
</html>
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 90일차 ch15SpringPage (0) | 2024.06.25 |
---|---|
쌍용교육 -JSP수업 89일차 ch14SpringThymeleadf(2) (0) | 2024.06.25 |
쌍용교육 -JSP수업 87일차 ch13SpringTiles(1) (0) | 2024.06.24 |
쌍용교육 -JSP수업 86일차 SpringBoot(1) (0) | 2024.06.21 |
쌍용교육 -JSP수업 85일차 SpringBoot[ch12SpringMybatisBoot] (0) | 2024.06.21 |
application.yml 그대로 복사해서 사용
jsp를 사용하지 않고 HTML을 사용하기 때문에 코드 수정이 필요.
mvc:
view: #view 경로 및 확장자 지정
prefix: /WEB-INF/views/
suffix: .jsp
여기를 삭제하고 thymeleadf 설정을 넣는다.
thymeleaf:
prefix: classpath:templates/
suffix: .html
check-template-location: true
enabled: true
mode: HTML5
cache: false #캐시를 사용하지 않음. 새로고침하면 변경사항이 바로 확인
src/main/resources => messages와css 폴더를 ch12프로젝트에 있는걸 복사해서 사용
kr.spring.board.vo => BoardVO
package kr.spring.board.vo;
import java.sql.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
public class BoardVO {
private int num;
@NotBlank
private String writer;
@NotBlank
private String title;
@NotBlank
private String passwd;
@NotEmpty
private String content;
private Date reg_date;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
@Override
public String toString() {
return "BoardVO [num=" + num + ", writer=" + writer + ", title=" + title + ", passwd=" + passwd + ", content="
+ content + ", reg_date=" + reg_date + "]";
}
}
kr.spring.board.dao => BoardMapper
package kr.spring.board.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import kr.spring.board.vo.BoardVO;
@Mapper
public interface BoardMapper {
public void insertBoard(BoardVO board);
@Select("SELECT COUNT(*) FROM aboard")
public int getBoardCount();
public List<BoardVO> getBoardList(Map<String,Integer>map);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
BoardMapper.xml 역시 ch12에서 복사해서 사용
kr.spring.board.service=>BoardService
package kr.spring.board.service;
import java.util.List;
import java.util.Map;
import kr.spring.board.vo.BoardVO;
public interface BoardService {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(Map<String,Integer>map);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
BoardServiceImpl
package kr.spring.board.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import kr.spring.board.dao.BoardMapper;
import kr.spring.board.vo.BoardVO;
@Service
@Transactional
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardMapper boardMapper;
@Override
public void insertBoard(BoardVO board) {
boardMapper.insertBoard(board);
}
@Override
public int getBoardCount() {
return boardMapper.getBoardCount();
}
@Override
public List<BoardVO> getBoardList(Map<String, Integer> map) {
return boardMapper.getBoardList(map);
}
@Override
public BoardVO getBoard(int num) {
return boardMapper.getBoard(num);
}
@Override
public void updateBoard(BoardVO board) {
boardMapper.updateBoard(board);
}
@Override
public void deleteBoard(int num) {
boardMapper.deleteBoard(num);
}
}
kr.spring.board.controller => BoardController (ch12에서 그대로 복사)
templates => views => selectList.html
그냥만들면 webapp으로 가기 때문에 위치를 변경해줘야된다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>게시판목록</title>
<link rel="stylesheet" th:href="@{/css/style/css}" type="text/css"> <!-- th: 를 쓰면 thymeleaf의 속성으로 적용. -->
</head>
<body>
<div class="page-main">
<h2>게시판 목록</h2>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='insert.do'">
</div>
<!-- thymeleaf는 태그를 쓰지않고 속성을 쓴다고 생각하면된다. thymeleaf는 HTML하나만으로 view를 구현함. -->
<!-- 기존의 <c:if>대신 th:if를 사용. 만약 false이면(0이 아니면) 이 div가 나오지않음 -->
<div class="result-display" th:if="${count == 0}">표시할 내용이 없습니다.</div>
<div th:if="${count > 0}">
<table>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<tr th:each="board : ${list}">
<td th:text="${board.num}"></td>
<!-- @{detail.do?num=${board.num}}에서 detail앞에 /를 넣으면 url형태이다. 안쓰면 파일형태 -->
<!-- ? 대신에 ()소괄호로 감싸줘야된다. -->
<td><a th:href="@{detail.do(num=${board.num})}" th:text="${board.title}"></a></td>
<td th:text="${board.writer}"></td>
<td th:text="${board.reg_date}"></td>
</tr>
</table>
<div class="align-center" th:utext="${page}"></div>
</div>
</div>
</body>
</html>
BoardController 내용수정
views/를 넣어줌
89라인
//뷰 이름 설정
mav.setViewName("views/selectList");
//글쓰기 폼 호출
@GetMapping("/insert.do")
public String form() {
return "views/insertForm";
}
templates => views =>insertForm.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<link rel="stylesheet" th:href="@{/css/style.css}" type="text/css">
</head>
<body>
<div class="page-main">
<h2>글쓰기</h2>
<!-- th:object : request에 저장되어있는 자바빈 호출 -->
<form action="insert.do" method="post" th:object="${boardVO}">
<ul>
<li>
<label for="writer">작성자</label>
<!-- th:field : 자바빈에 필드 지정 (id와 클라이언트가 넣은 값value가 들어감)--> <!-- *{writer} 는 boardVO.writer라고 생각하면됨 -->
<input type="text" name="writer" th:field="*{writer}" th:errorclass="field-error">
<span th:errors="*{writer}" class="error-color"></span>
</li>
<li>
<label for="title">제목</label>
<input type="text" name="title" th:field="*{title}" th:errorclass="field-error">
<span th:errors="*{title}" class="error-color"></span>
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd" th:field="*{passwd}" th:errorclass="field-error">
<span th:errors="*{passwd}" class="error-color"></span>
</li>
<li>
<label for="content">내용</label>
<textarea th:field="*{content}" th:errorclass="field-error"></textarea>
<span th:errors="*{content}" class="error-color"></span>
</li>
</ul>
<div class="align-center">
<input type="submit" value="등록">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form>
</div>
</body>
</html>
BoardMapper.java 내용추가
@Select("SELECT * FROM aboard WHERE num=#{num}")
public BoardVO getBoard(int num);
BoardController.java 내용추가
views/ 추가
//글상세
@RequestMapping("/detail.do")
public ModelAndView detail(int num) {
BoardVO board =
boardService.getBoard(num);
return new ModelAndView("views/selectDetail","board",board);
}
templates => views =>selectDetail.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글상세</title>
<link rel="stylesheet" th:href="@{/css/style.css}" type="text/css">
</head>
<body>
<div class="page-main">
<h2 th:text="${board.title}"></h2>
<p>
<!-- 1,2번 방법중 어떤것을 써도 상관없음 -->
<span th:text="'글번호 :' + ${board.num}"></span><br><!-- 1번 방법 -->
<span>작성자 : [[${board.writer}]]</span><br><!-- 2번 방법 -->
<span>작성일 : [[${board.reg_date}]]</span>
</p>
<hr width="100%" size="1" noshade="noshade">
<p th:text="${board.content}"></p>
<div class="align-center">
<!-- th:onclick 을 쓸 떄는 ""안에 | 를 맨끝에 써줘야됨. 자바스크립트를 쓰기 위해 파이프(|)를 씀 -->
<input type="button" value="수정" th:onclick="|location.href='@{update.do(num=${board.num})}'|">
<input type="button" value="삭제" th:onclick="|location.href='@{delete.do(num=${board.num})}'|">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</div>
</body>
</html>
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 90일차 ch15SpringPage (0) | 2024.06.25 |
---|---|
쌍용교육 -JSP수업 89일차 ch14SpringThymeleadf(2) (0) | 2024.06.25 |
쌍용교육 -JSP수업 87일차 ch13SpringTiles(1) (0) | 2024.06.24 |
쌍용교육 -JSP수업 86일차 SpringBoot(1) (0) | 2024.06.21 |
쌍용교육 -JSP수업 85일차 SpringBoot[ch12SpringMybatisBoot] (0) | 2024.06.21 |