저번장에서는 검색기능을 구현했는데요
이제 해당 게시물의 댓글목록을 보여주는 기능을 추가해보겠습니다.
1. 댓글 테이블 작성
CREATE TABLE reply (
reply_number int NOT NULL AUTO_INCREMENT,
board_number int NOT NULL DEFAULT '0',
replytext varchar(1000) NOT NULL,
replyer varchar(50) NOT NULL,
create_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_date timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (reply_number),
CONSTRAINT fk_board FOREIGN KEY (board_number) REFERENCES board(board_number) ON DELETE CASCADE
);
게시판에서 댓글은 어떤 특정 게시물에 종속되어 있기 때문에 게시물을 구분할 수 있어야 합니다.
그래서 board 테이블에 있는 board_number(게시물 번호), 댓글 구분에 필요한 댓글 번호(reply_number)가 있습니다.
댓글은 게시물이 있어야 작성할 수 있기 때문에 댓글테이블에 있는 board_number는 값을 추가하는게 아니라
기존에 있던 board 테이블에 있는 board_number를 따라가야 합니다.
그렇기 때문에 쿼리 맨아래 쪽에 foreign key를 사용했습니다.
foreign key는 대상 테이블의 컬럼과 참조하는 테이블의 컬럼값이 존재하는지를 확인하고, 참조하는 테이블에 값이 없을 경우 에러를 발생합니다.
이렇게 댓글 쿼리를 작성했으니 해당 게시물에 댓글이 잘달리는지 확인해보겠습니다.
# 댓글작성
insert into reply(board_number, replytext, replyer)
values(4, "댓글 테스트" "슥이");
# 해당 댓글 조회
select *
from reply
where board_number= 4 and replyer="슥이";
정상적으로 board_number가 4이면서 댓글 작성자가 '슥이'인 사용자가 단 댓글을 확인할 수 있습니다.
2. 댓글 VO 작성
package kr.co.web.domain;
import java.util.Date;
public class ReplyVO {
private Integer reply_number;
private Integer board_number;
private String replytext;
private String replyer;
private Date create_date;
private Date update_date;
public Integer getReply_number() {
return reply_number;
}
public void setReply_number(Integer reply_number) {
this.reply_number = reply_number;
}
public Integer getBoard_number() {
return board_number;
}
public void setBoard_number(Integer board_number) {
this.board_number = board_number;
}
public String getReplytext() {
return replytext;
}
public void setReplytext(String replytext) {
this.replytext = replytext;
}
public String getReplyer() {
return replyer;
}
public void setReplyer(String replyer) {
this.replyer = replyer;
}
public Date getCreate_date() {
return create_date;
}
public void setCreate_date(Date create_date) {
this.create_date = create_date;
}
public Date getUpdate_date() {
return update_date;
}
public void setUpdate_date(Date update_date) {
this.update_date = update_date;
}
}
3. replyMapper.xml 작성
<mapper namespace="replyMapper">
<!-- 댓글 조회 -->
<select id="readReply" resultType="ReplyVO">
select reply_number, replytext, replyer, create_date
from reply
where board_number = #{board_number}
</select>
</mapper>
댓글 조회 쿼리에 resultType을 달랑 "ReplyVO"라고 선언했는데요.
프로젝트를 진행하다가 왜 갑자기 이렇게 선언하는지 기억이 안나실 수 있습니다.
이유는 저희가 /src/main/resources에 mybatis-config.xml을 만들었는데요
<?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>
<typeAliases>
<package name="kr.co.web.domain" />
</typeAliases>
</configuration>
다음과 같이 typeAliases태그로 resultType을 간단하게 사용할 수 있도록
kr.co.web.domain에 있는 VO들을 알아서 인식해라! 라고 선언해주면
mapper에서는 해당 VO인 ReplyVO만 적으면 알아서 인식을 해주는 역할을 하고 있습니다.
4. DAO 작성
<!-- ReplyDAO -->
package kr.co.web.persistence;
import java.util.List;
import kr.co.web.domain.Criteria;
import kr.co.web.domain.ReplyVO;
public interface ReplyDAO {
public List<ReplyVO> readReply(int board_number) throws Exception;
}
<!-- ReplyDAOImpl -->
package kr.co.web.persistence;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import kr.co.web.domain.Criteria;
import kr.co.web.domain.ReplyVO;
@Repository
public class ReplyDAOImpl implements ReplyDAO{
@Inject
SqlSession session;
private static final String NS = "replyMapper";
private static final String READ = NS + ".readReply";
@Override
public List<ReplyVO> readReply(int board_number) throws Exception {
return session.selectList(READ, board_number);
}
}
5. SERVICE 작성
<!-- ReplyService -->
package kr.co.web.service;
import java.util.List;
import kr.co.web.domain.Criteria;
import kr.co.web.domain.ReplyVO;
public interface ReplyService {
public List<ReplyVO> readReply(int board_number) throws Exception;
}
<!-- ReplyServiceImpl -->
package kr.co.web.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.co.web.domain.Criteria;
import kr.co.web.domain.ReplyVO;
import kr.co.web.persistence.ReplyDAO;
@Service
public class ReplyServiceImpl implements ReplyService{
@Inject
ReplyDAO replyDAO;
@Override
public List<ReplyVO> readReply(int board_number) throws Exception {
return replyDAO.readReply(board_number);
}
}
6. BoardController 수정
<!-- BoardController -->
@Inject
private ReplyService replyService; // ReplyService 주입
.......
@RequestMapping(value = "/readView", method = RequestMethod.GET)
public String readReply(BoardVO board, @ModelAttribute("cri") Criteria cri, Model model) throws Exception {
logger.info("read");
model.addAttribute("BoardVO", service.read(board.getBoard_number()));
model.addAttribute("cri", cri);
List<ReplyVO> replyList = replyService.readReply(board.getBoard_number()); // 추가
model.addAttribute("replyList", replyList); // 추가
return "board/readView";
}
게시판 조회하는 메서드에 댓글을 불러올 수 있는 코드를 추가했습니다.
댓글을 따로 컨트롤러를 만들어서 하지 않은 이유는
댓글은 게시물에 종속되어 있기 때문이며,
ajax를 사용하지 않았기 때문입니다.
후에는 ajax를 구현해 댓글기능을 구현할 예정입니다.
7. readView.jsp에 댓글 목록 추가
<!-- 댓글 -->
<div id="reply">
<ol class="replyList">
<c:forEach items="${replyList}" var="replyList">
<li>
<p>
작성자 : ${replyList.replyer}<br />
작성 날짜 : <fmt:formatDate value="${replyList.create_date}" pattern="yyyy-MM-dd" />
</p>
<p>${replyList.replytext}</p>
</li>
</c:forEach>
</ol>
</div>
8. 댓글 목록 테스트
정상적으로 댓글 목록이 출력되었습니다.
그리고 해당 댓글에 수정, 삭제와 댓글 작성 부분은
제가 먼저 해당 기능을 작성하고 포스팅한것이기 때문에 없다고 생각하시면 됩니다!!!
'JAVA > blog' 카테고리의 다른 글
댓글 구현(3) - 게시판 댓글 수정, 삭제 (0) | 2020.07.29 |
---|---|
댓글 구현(2) - 게시판 댓글 작성 (0) | 2020.07.27 |
검색(3) (0) | 2020.07.24 |
jQuery .val() - form의 값을 가져거나 값을 설정하는 메서드 (0) | 2020.07.23 |
검색(2) (0) | 2020.07.23 |