코드로 배우는 스프링 웹 프로젝트-20. 댓글과 댓글 수에 대한 처리
코드로 배우는 스프링 웹 프로젝트 - 개정판
2019년 7월 10일 인쇄판
Part5. AOP와 트랜잭션
Chapter20. 댓글과 댓글 수에 대한 처리
tbl_reply 테이블에 insert 하고, tbl_board 테이블에 댓글 수를 의미하는 replyCnt 칼럼 추가. 해당 게시물 댓글의 수를 update 한다.
alter table tbl_board add(replycnt number default 0);
기존에 댓글이 존재했다면 replyCnt에 반영해 두어야 하므로 아래 쿼리 실행.
update tbl_board set replycnt = (select count(rno) from tbl_reply
where tbl_reply.bno = tbl_board.bno);
20.1 프로젝트 수정
BoardVO 클래스와 MyBatis의 SQL, BoardService를 수정하자.
ex03 혹은 jex03 프로젝트를 수정하는 형태로 적용.
20.1.1 BoardVO, BoardMapper 수정
댓글의 숫자를 의미하는 변수 추가.
BoardVO 클래스
package org.zerock.domain;
import java.util.Date;
import lombok.Data;
@Data
public class BoardVO {
private Long bno;
private String title;
private String content;
private String writer;
private Date regdate;
private Date updateDate;
private int replyCnt;
}
BoardMapper interface
package org.zerock.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
public interface BoardMapper {
//@Select("select * from tbl_board where bno > 0")
public List<BoardVO> getList();
public List<BoardVO> getListWithPaging(Criteria cri);
public void insert(BoardVO board);
public void insertSelectKey(BoardVO board);
public BoardVO read(Long bno);
public int delete(Long bno);
public int update(BoardVO board);
public int getTotalCount(Criteria cri);
public void updateReplyCnt(@Param("bno") Long bno, @Param("amount") int amount);
}
MyBatis에선 SQL을 처리하기 위해 기본적으로 하나의 파라미터 타입을 사용하기 때문에 2개 이상의 데이터를 전달하려면 @Param 어노테이션을 사용해야 함.
BoardMapper.xml에 추가.
<update id="updateReplyCnt">
update tbl_board set replycnt = replycnt + #{amount} where bno = #{bno}
</update>
</mapper>
<select id="getListWithPaging"
resultType="org.zerock.domain.BoardVO">
<![CDATA[
select
bno, title, content, writer, regdate, updateDate, replycnt
from
(
select /*+INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content, writer, regdate, updateDate, replycnt
from
tbl_board
where
]]>
<include refid="criteria"></include>
<![CDATA[
rownum<= #{pageNum} * #{amount}
)
where rn > (#{pageNum}-1) * #{amount}
]]>
</select>
20.1.2 ReplyServiceImpl의 트랜잭션 처리
ReplyServiceImpl 클래스는 기존에 ReplyMapper만 사용했지만 반정규화 처리가 되며 BoardMapper도 함께 이용해야 한다.
ReplyServiceImpl에 새로운 댓글이 추가되거나 삭제되는 상황이 되면, 트랜잭션 처리로 해 주어야 한다.
ReplyServiceImpl 수정.
package org.zerock.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zerock.domain.Criteria;
import org.zerock.domain.ReplyPageDTO;
import org.zerock.domain.ReplyVO;
import org.zerock.mapper.BoardMapper;
import org.zerock.mapper.ReplyMapper;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@Service
@Log4j
public class ReplyServiceImpl implements ReplyService{
@Setter(onMethod_ = @Autowired)
private ReplyMapper mapper;
@Setter(onMethod_ = @Autowired)
private BoardMapper boardMapper;
@Transactional
@Override
public int register(ReplyVO vo) {
log.info("register......" + vo);
return mapper.insert(vo);
}
@Override
public ReplyVO get(Long rno) {
log.info("get......" + rno);
return mapper.read(rno);
}
@Override
public int modify(ReplyVO vo) {
log.info("modify......" + vo);
return mapper.update(vo);
}
@Transactional
@Override
public int remove(Long rno) {
log.info("remove......" + rno);
return mapper.delete(rno);
}
@Override
public List<ReplyVO> getList(Criteria cri, Long bno) {
log.info("get Reply List of a Board " + bno);
return mapper.getListWithPaging(cri, bno);
}
@Override
public ReplyPageDTO getListPage(Criteria cri, Long bno) {
return new ReplyPageDTO(
mapper.getCountByBno(bno),
mapper.getListWithPaging(cri, bno));
}
}
BoardMapper를 자동 주입 대신 @Setter로 주입 가능.
댓글 등록/삭제 메서드에 @Transactional 처리가 필요.
댓글 등록은 파라미터로 받는 ReplyVO 내에 게시물 번호가 존재하지만 댓글의 삭제는 파라미터에 댓글 번호만 받으므로 해당 댓글의 게시물을 알아내는 과정이 필요하다.
20.1.3 화면 수정
게시물의 목록 화면에선 댓글 숫자가 출력되도록 수정해 줄 필요가 있다.
list.jsp 일부 수정.
<tbody>
<c:forEach items="${list}" var="board">
<tr class="odd gradeX">
<td>
<c:out value="${board.bno}"/>
</td>
<td>
<a class='move' href='<c:out value="${board.bno}"/>'>
<c:out value="${board.title }"/>
<b> [ <c:out value="${board.replyCnt }" /> ]</b>
</a>
</td>
<td><c:out value="${board.writer}"/></td>
<td><fmt:formatDate pattern="yyyy-MM-dd" value="${board.regdate }"/></td>
<td><fmt:formatDate pattern="yyyy-MM-dd" value="${board.updateDate }"/></td>
</tr>
</c:forEach>
</tbody>
'개발 공부 > Spring' 카테고리의 다른 글
코드로 배우는 스프링 웹 프로젝트-22. 파일 업로드 상세 처리 (0) | 2020.07.15 |
---|---|
코드로 배우는 스프링 웹 프로젝트-part6.파일 업로드 처리-21.파일 업로드 방식 (0) | 2020.07.15 |
코드로 배우는 스프링 웹 프로젝트-19.스프링에서 트랜잭션 관리 (0) | 2020.07.14 |
코드로 배우는 스프링 웹 프로젝트-Part5.AOP와 트랜잭션-chap18.AOP라는 패러다임 (0) | 2020.07.14 |
코드로 배우는 스프링 웹 프로젝트-17.Ajax 댓글 처리 (0) | 2020.07.14 |