22.06.09
JDBC(DB연동) Board연습
jsp보다 훨씬 코드가 간결해졌다.
하지만 자동 빈객체등록,의존성주입하는 어노테이션 사용에 주의하고,
쿼리문에 따라 사용하는 메서드가 다르다는 점을 주의하자.
CREATE TABLE jdbc_board(
board_no NUMBER PRIMARY KEY,
writer VARCHAR2(30) NOT NULL,
title VARCHAR2(100) NOT NULL,
content VARCHAR2(1000)
);
CREATE SEQUENCE bid_seq
START WITH 1
INCREMENT BY 1
MAXVALUE 1000
NOCYCLE
NOCACHE;
게시물 번호는 SEQUENCE 이용해서 자동으로 올려준다.
<script>
package com.spring.db.model;
public class BoardVO {
private int boardNo;
private String writer;
private String title;
private String content;
public BoardVO() { }
public BoardVO(int boardNo, String writer, String title, String content) {
super();
this.boardNo = boardNo;
this.writer = writer;
this.title = title;
this.content = content;
}
public int getBoardNo() {
return boardNo;
}
public void setBoardNo(int boardNo) {
this.boardNo = boardNo;
}
...
@Override
public String toString() {
return "BoardVO [boardNo=" + boardNo + ", writer=" + writer + ", title=" + title + ", content=" + content + "]";
}
}
</script>
사용자 이름으로 검색하는 getSearchList(String keyword) 메서드 추가.
<script>
package com.spring.db.service;
public interface IBoardService {
//게시글 등록
void insertArticle(BoardVO vo);
//전제 게시글 목록
List<BoardVO> getArticles();
//게시글 상세 보기
BoardVO getArticle(int bId);
//사용자로 글 검색
List<BoardVO> getSearchList(String keyword);
//게시글 삭제
void deleteArticle(int bId);
//게시글 수정
void updateArticle(BoardVO vo);
}
</script>
이제는 글번호가 객체에 들어있기 때문에 굳이 따로 번호를 가지고 올 필요 없다.
<script>
package com.spring.db.service;
@Service
public class BoardService implements IBoardService {
@Autowired
private IBoardDAO dao;
@Override
public void insertArticle(BoardVO vo) {
dao.insertArticle(vo);
}
@Override
public List<BoardVO> getArticles() {
return dao.getArticles();
}
@Override
public BoardVO getArticle(int bId) {
return dao.getArticle(bId);
}
@Override
public void deleteArticle(int bId) {
dao.deleteArticle(bId);
}
@Override
public void updateArticle(BoardVO vo) {
dao.updateArticle(vo);
}
@Override
public List<BoardVO> getSearchList(String keyword) {
return dao.getSearchList("%"+keyword+"%");
//sql에서 LIKE쓰기 위해서 와일드카드 사용
}
}
</script>
<script>
package com.spring.db.repository;
@Repository
public class BoardDAO implements IBoardDAO {
//# Spring-jdbc 방식의 처리 : JdbcTemplate 활용하기 위해 변수 선언
@Autowired
private JdbcTemplate template;
//SELECT문에서 사용하기 위한 내부클래스 선언
class BoardMapper implements RowMapper<BoardVO> {
@Override
public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException {
return new BoardVO(rs.getInt("board_no"), rs.getString("writer"),
rs.getString("title"), rs.getString("content"));
//변수 선언 없이 return에 바로 BoardVO객체 생성해서 리턴
}
}
@Override
public void insertArticle(BoardVO vo) {
String sql = "INSERT INTO jdbc_board VALUES(bid_seq.NEXTVAL,?,?,?)";
template.update(sql, vo.getWriter(), vo.getTitle(), vo.getContent());
}
@Override
public List<BoardVO> getArticles() {
String sql = "SELECT * FROM jdbc_board ORDER BY board_no DESC";
return template.query(sql, new BoardMapper());
}
@Override
public BoardVO getArticle(int bId) {
String sql = "SELECT * FROM jdbc_board WHERE board_no = ?";
return template.queryForObject(sql, new BoardMapper(), bId);
}
@Override
public void deleteArticle(int bId) {
String sql = "DELETE FROM jdbc_board WHERE board_no = ?";
template.update(sql, bId);
}
@Override
public void updateArticle(BoardVO vo) {
String sql = "UPDATE jdbc_board SET writer=?,title=?,content=? WHERE board_no=?";
template.update(sql, vo.getWriter(), vo.getTitle(), vo.getContent(), vo.getBoardNo());
}
@Override
public List<BoardVO> getSearchList(String keyword) {
String sql = "SELECT * FROM jdbc_board WHERE writer LIKE ? ORDER BY board_no DESC";
return template.query(sql, new BoardMapper(), keyword);
}
}
</script>
<script>
package com.spring.db.controller;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
private IBoardService service;
// 글 작성 화면을 열어주는 메서드
@GetMapping("/write")
public void write() { }
// 작성된 글 등록 처리 요청 메서드
@PostMapping("/write")
public String write(BoardVO vo) {
service.insertArticle(vo);
return "redirect:/board/list";
}
// 글 목록 화면 요청
@GetMapping("/list")
public void list(Model model) {
model.addAttribute("articles", service.getArticles());
}
// 글 내용 상세보기 요청 처리 메서드
@GetMapping("/content")
public void content(@RequestParam("boardNo") int boardNo, Model model) {
model.addAttribute("article", service.getArticle(boardNo));
}
// 사용자 이름으로 검색하기
@GetMapping("/searchList")
public String searchList(@RequestParam("keyword") String keyword,Model model) {
model.addAttribute("articles",service.getSearchList(keyword));
return "board/list";
} //list.jsp 재활용을 위해 model이름 'articles'재사용
// 글 수정하기 화면으로 이동 요청
@GetMapping("/modify")
public void modify(@RequestParam("boardNo") int boardNo, Model model) {
System.out.println("/board/modify: GET");
model.addAttribute("article", service.getArticle(boardNo));
}
// 글 수정 요청 메서드
@PostMapping("/modify")
public String modify(BoardVO vo) {
System.out.println("/board/modify: POST");
service.updateArticle(vo);
return "redirect:/board/content?boardNo=" + vo.getBoardNo();
}
// 글 삭제하기
@GetMapping("/delete")
public String delete(@RequestParam("boardNo") int boardNo) {
service.deleteArticle(boardNo);
return "redirect:/board/list";
}
}
</script>
사용자 이름으로 검색하는 from태그 추가.
<body>
<h2>게시글 목록</h2>
<table border="1">
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>비고</th>
</tr>
<c:forEach var="article" items="${articles}">
<tr>
<td>${article.boardNo}</td>
<td>
<a href="<c:url value='/board/content?boardNo=${article.boardNo}'/>">${article.title}</a>
</td>
<td>${article.writer}</td>
<td>
<a href="<c:url value='/board/delete?boardNo=${article.boardNo}'/>">[삭제]</a>
</td>
</tr>
</c:forEach>
</table>
<br>
<form action="<c:url value='/board/searchList'/>">
<input type="text" name="keyword" placeholder="작성자 이름을 입력하세요.">
<input type="submit" value="검색">
</form>
<a href="<c:url value='/board/write' />">게시물 작성하기</a>
</body>