Spring
[Spring] 게시판 CRUD
아잠만_
2024. 7. 22. 14:59
고려사항
- 게시판 조회/삽입/수정/삭제 수행할 것
- 게시글 줄을 선택하면 해당하는 게시판의 자세한 글을 볼 수 있게 할 것
- 삭제 시에 재확인할 것 (confirm)
- 수정 시에 같은 페이지에서 처리
CREATE TABLE JDBC_BOARD
(
BOARD_NO NUMBER,
BOARD_TITLE VARCHAR2(100),
BOARD_WRITER VARCHAR2(50),
BOARD_DATE DATE,
BOARD_CNT NUMBER DEFAULT 0,
BOARD_CONTENT VARCHAR2(1000),
CONSTRAINT PK_JDBC_BOARD PRIMARY KEY (BOARD_NO)
);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (1,'첫번째 게시글 제목','홍길동',to_date('2024/05/22','yyyy/MM/DD'),1);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (2,'두번째 게시글','이순신',to_date('2024/05/22','yyyy/MM/DD'),0);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (6,'연습용','작성자',to_date('2024/05/22','yyyy/MM/DD'),0);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (4,'글번호는 몇번?','강감찬',to_date('2024/05/22','yyyy/MM/DD'),1);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (7,'mybatis게시판 연습','이몽룡',to_date('2024/05/27','yyyy/MM/DD'),2);
Insert into JDBC_BOARD (BOARD_NO,BOARD_TITLE,BOARD_WRITER,BOARD_DATE,BOARD_CNT) values (8,'log연습용','이순신',to_date('2024/05/27','yyyy/MM/DD'),0);
COMMIT;
JSP
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>게시글 목록</title>
<script>
window.onload = function(){
let board = document.querySelectorAll('.board');
board.forEach(function(e){
e.addEventListener('click',function(e){
let tr = e.target.parentNode;
let no = tr.getAttribute('idx');
console.log(no);
location.href = "/jdbcBoard/detail?boardNo="+no;
})
})
}
</script>
<style>
.board:hover{
background: skyblue;
}
</style>
</head>
<body>
<h3>게시글 목록</h3>
<a href="/jdbcBoard/create">게시글 등록</a>
<table border="1">
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
<c:forEach var="vo" items="${list}">
<tr class="board" idx="${vo.boardNo}">
<td>${vo.boardNo}</td>
<td>${vo.boardTitle}</td>
<td>${vo.boardWriter}</td>
<td><fmt:formatDate value="${vo.boardDate}" pattern="yyyy-MM-dd"/></td>
<td>${vo.boardCnt}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!-- 상단에 작성해줍니다. -->
<%
pageContext.setAttribute("LF", "\n");
pageContext.setAttribute("BR", "<br/>");
%>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
window.onload = function(){
let editBtn = document.querySelector('#edit');
let delBtn = document.querySelector('#delete');
let view = document.querySelector('#viewForm');
let edit = document.querySelector('#editForm');
editBtn.addEventListener('click', function(e){
view.hidden = true;
edit.hidden = false;
})
delBtn.addEventListener('click', function(e){
if(confirm("정말 삭제하시겠습니까?")){
location.href = "/jdbcBoard/delete?boardNo=${vo.boardNo}";
}
})
}
</script>
</head>
<body>
<div id="viewForm">
<h3>게시글 조회</h3>
<table border="1">
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
<tr>
<td>${vo.boardNo}</td>
<td>${vo.boardTitle}</td>
<td>${vo.boardWriter}</td>
<td>
<fmt:formatDate value="${vo.boardDate}" pattern="yyyy-MM-dd"/> <fmt:formatDate value="${vo.boardDate}" pattern="HH:mm:ss"/>
</td>
<td>${vo.boardCnt}</td>
</tr>
<tr>
<td colspan="5">
<c:out value="${fn:replace(vo.boardContent, LF, BR)}" escapeXml="false"/>
</td>
</tr>
</table>
<input type="button" value="수정" id="edit">
<input type="button" value="삭제" id="delete">
<input type="button" value="목록" onclick="location.href='/jdbcBoard/list'">
</div>
<div id="editForm" hidden>
<h3>게시글 수정</h3>
<form action="/jdbcBoard/update" method="post">
<input type="hidden" name="boardNo" value="${vo.boardNo}">
<p>
<label>제목</label>
<input type="text" name="boardTitle" value="${vo.boardTitle}" placeholder="제목" required="required">
</p>
<p>
<label>작성자</label>
<input type="text" name="boardWriter" value="${vo.boardWriter}" placeholder="작성자" required="required">
</p>
<p>
<textarea rows="3" cols="50" name="boardContent" placeholder="내용">${vo.boardContent}</textarea>
</p>
<p>
<input type="submit" value="완료">
<input type="button" value="취소" onclick="location.href='/jdbcBoard/detail?boardNo=${vo.boardNo}'">
</p>
</form>
</div>
</body>
</html>
create.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h3>게시글 작성</h3>
<form action="/jdbcBoard/createPost" method="post">
<p>
<input type="text" name="boardTitle" placeholder="제목" required="required">
</p>
<p>
<input type="text" name="boardWriter" placeholder="작성자" required="required">
</p>
<p>
<textarea rows="3" cols="50" name="boardContent" placeholder="내용"></textarea>
</p>
<p>
<input type="submit" value="저장">
</p>
</form>
</body>
</html>
JAVA
JdbcBoardVO.java
package kr.or.ddit.vo;
import java.util.Date;
import lombok.Data;
@Data
public class JdbcBoardVO {
private int boardNo; // 번호
private String boardTitle; // 제목
private String boardWriter; // 작성자
private Date boardDate; // 작성일
private int boardCnt; // 조회수
private String boardContent; // 내용
}
JdbcBoardController.java
package kr.or.ddit.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import kr.or.ddit.service.JdbcBoardService;
import kr.or.ddit.vo.JdbcBoardVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class JdbcBoardController {
@Autowired
JdbcBoardService service;
@RequestMapping (value="/jdbcBoard/list")
public ModelAndView list() {
ModelAndView mav = new ModelAndView();
mav.setViewName("jdbcBoard/list");
List<JdbcBoardVO> list = this.service.list();
mav.addObject("list", list);
return mav;
}
@RequestMapping (value="/jdbcBoard/create")
public ModelAndView create() {
ModelAndView mav = new ModelAndView();
mav.setViewName("jdbcBoard/create");
return mav;
}
@RequestMapping (value="/jdbcBoard/createPost", method=RequestMethod.POST)
public ModelAndView createPost(JdbcBoardVO bvo) {
ModelAndView mav = new ModelAndView();
int result = this.service.createPost(bvo);
mav.setViewName("redirect:/jdbcBoard/list");
return mav;
}
@RequestMapping (value="/jdbcBoard/detail")
public ModelAndView detail(JdbcBoardVO bvo) {
ModelAndView mav = new ModelAndView();
int result = this.service.cntChange(bvo);
bvo = this.service.detail(bvo);
mav.setViewName("jdbcBoard/detail");
mav.addObject("vo", bvo);
return mav;
}
@RequestMapping (value="/jdbcBoard/update", method=RequestMethod.POST)
public ModelAndView update(JdbcBoardVO bvo) {
ModelAndView mav = new ModelAndView();
int result = this.service.update(bvo);
mav.setViewName("redirect:/jdbcBoard/detail?boardNo="+bvo.getBoardNo());
return mav;
}
@RequestMapping (value="/jdbcBoard/delete")
public ModelAndView delete(JdbcBoardVO bvo) {
ModelAndView mav = new ModelAndView();
int result = this.service.delete(bvo);
mav.setViewName("redirect:/jdbcBoard/list");
return mav;
}
}
JdbcBoardService.java
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.JdbcBoardVO;
public interface JdbcBoardService {
public List<JdbcBoardVO> list();
public JdbcBoardVO detail(JdbcBoardVO bvo);
public int createPost(JdbcBoardVO bvo);
public int cntChange(JdbcBoardVO bvo);
public int update(JdbcBoardVO bvo);
public int delete(JdbcBoardVO bvo);
}
JdbcBoardServiceImpl.java
package kr.or.ddit.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.or.ddit.dao.JdbcBoardDao;
import kr.or.ddit.service.JdbcBoardService;
import kr.or.ddit.vo.JdbcBoardVO;
@Service
public class JdbcBoardServiceImpl implements JdbcBoardService {
@Autowired
JdbcBoardDao dao;
@Override
public List<JdbcBoardVO> list() {
return this.dao.list();
}
@Override
public JdbcBoardVO detail(JdbcBoardVO bvo) {
return this.dao.detail(bvo);
}
@Override
public int createPost(JdbcBoardVO bvo) {
return this.dao.createPost(bvo);
}
@Override
public int cntChange(JdbcBoardVO bvo) {
return this.dao.cntChange(bvo);
}
@Override
public int update(JdbcBoardVO bvo) {
return this.dao.update(bvo);
}
@Override
public int delete(JdbcBoardVO bvo) {
return this.dao.delete(bvo);
}
}
JdbcBoardDao.java
package kr.or.ddit.dao;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.JdbcBoardVO;
@Repository
public class JdbcBoardDao {
@Autowired
SqlSessionTemplate sst;
public int createPost(JdbcBoardVO bvo) {
return this.sst.insert("board.createPost", bvo);
}
public JdbcBoardVO detail(JdbcBoardVO bvo) {
return this.sst.selectOne("board.detail", bvo);
}
public List<JdbcBoardVO> list() {
return this.sst.selectList("board.list");
}
public int cntChange(JdbcBoardVO bvo) {
return this.sst.update("board.cnt", bvo);
}
public int update(JdbcBoardVO bvo) {
return this.sst.update("board.update", bvo);
}
public int delete(JdbcBoardVO bvo) {
return this.sst.delete("board.delete", bvo);
}
}
Mybatis
TypeAlias설정
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
[마이바티스] 스프링에서 "_"를 사용한 컬럼명을 사용 시(BOOK 테이블의 BOOK_ID)
카멜케이스로 읽어줌(bookId)
ex) 테이블 컬러명이 member_id인 경우 jsp화면단에서 이 값을 사용 시 memberId로 사용
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 자주 사용하는 타입의 별칭을 세팅 -->
<typeAliases>
<typeAlias type="kr.or.ddit.vo.BookVO" alias="bookVo" />
<typeAlias type="kr.or.ddit.vo.LprodVO" alias="LprodVo" />
<typeAlias type="kr.or.ddit.vo.JdbcBoardVO" alias="boardVo" />
</typeAliases>
</configuration>
jdbcBoard_SQL.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="board">
<select id="list" resultType="boardVo">
select *
from jdbc_board
order by board_no desc
</select>
<insert id="createPost" parameterType="boardVo">
<selectKey order="BEFORE" resultType="int" keyProperty="boardNo">
select nvl(max(board_no),0)+1
from jdbc_board
</selectKey>
insert into jdbc_board (board_no,board_title,board_writer,board_date,board_cnt,board_content)
values (#{boardNo}, #{boardTitle}, #{boardWriter}, sysdate, 0, #{boardContent})
</insert>
<select id="detail" resultType="boardVo" parameterType="boardVo">
select *
from jdbc_board
where board_no=#{boardNo}
</select>
<update id="cnt" parameterType="boardVo">
<selectKey order="BEFORE" resultType="int" keyProperty="boardCnt">
select board_cnt+1
from jdbc_board
where board_no=#{boardNo}
</selectKey>
update jdbc_board
set board_cnt = #{boardCnt}
where board_no = #{boardNo}
</update>
<update id="update" parameterType="boardVo">
update jdbc_board
set board_writer = #{boardWriter},
board_content = #{boardContent},
board_title = #{boardTitle}
where board_no = #{boardNo}
</update>
<delete id="delete" parameterType="boardVo">
delete jdbc_board
where board_no=#{boardNo}
</delete>
</mapper>