Keep going

댓글과 댓글 수에 대한 처리 본문

Records/Spring Framework

댓글과 댓글 수에 대한 처리

코딩천재홍 2021. 3. 26. 04:45

 

tbl_reply 테이블에 insert하고, tb1_board 테이블에는 댓글의 수를 의미하는 replyCnt라는 칼럼을 추가해서 해당 게시물 댓글의 수를 update 한다.

 

tb1_board 테이블에는 replyCnt 칼럼을 추가

alter table tb1_board add (replycnt number default 0);
cs

 

기존의 댓글에 존재했다면 replyCnt에 반영해 두어야 하므로 아래의 쿼리를 실행한다.

update tb1_board set replycnt = (select count(rno) from tbl_reply 
where tbl_reply.bno = tb1_board.bno);
cs

 


20.1 프로젝트 수정

데이터베이스가 수정 되었으므로 BoardVO 클래스, MyBatis의 SQL, BoardService를 수정한다.

 

 

  • 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;
}
 
cs

 

 

  • BoardMapper 인터페이스
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 tb1_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);
 
}
 
cs

- 새로 추가된 updateReplyCnt( )는 해당 게시물의 번호인 bno와 증가나 감소를 의미하는 amount 변수에 파라미터를 받을 수 있도록 처리한다. 댓글이 등록하면 1이 증가하고, 삭제 되면 1이 감소하기 때문이다.

- MyBatis와 SQL 을 처리하기 위해서는 기본적으로 하나의 파라미터 타입을 사용하기 때문에 위와 같이 2개 이상의 데이터를 전달하려면 @Param이라는 어노테이션을 이용해서 처리할 수 있다.

 

 

  • BoardMapper.xml
<update id="updateReplyCnt">
        update tbl_board set replycnt = replycnt + #{amount} where bno = #{bno}
</update>
 
 
<select id="getListWithPaging"
        resultType="org.zerock.domain.BoardVO">
    <![CDATA[
        select
            bno, title, content, writer, regdate, updateDate, replycnt
        from 
        (
            select /*+INDEX_DESC(tb1_board pk_board) */
                rownum rn, bno, title, content, writer, regdate, updateDate, replycnt
            from
                tb1_board
            where 
       ]]>
    <include refid="criteria"></include>
       <![CDATA[
            rownum<= #{pageNum} * #{amount}
        )
        where rn > (#{pageNum}-1) *  #{amount}
    ]]>
</select>
 
 
cs

 

 

 

  • ReplyServiceImpl의 트랜잭션 처리
    • ReplyServiceImpl 클래스는 기존에는 ReplyMapper만을 이용했지만, 반정규화 처리가 되면서 BoardMapper를 같이 이용해야 하는 상황이 되었다.
    • ReplyServiceImpl에서 새로운 댓글이 추가되거나 삭제되는 상황이 되면 BoardMapper와 ReplyMapper 를 같이 이용해서 처리하고, 이 작업은 트랜잭션으로 처리되어야 한다.
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);
        boardMapper.updateReplyCnt(vo.getBno(), 1);
        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);
        
        ReplyVO vo = mapper.read(rno);
        
        boardMapper.updateReplyCnt(vo.getBno(), -1);
        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));
    }
 
}
 
cs

- 기존과 달라지는 점은 기존에는 ReplyMapper만을 주입하기 때문에 자동주입을 이용할 수 있었지만, 추가적으로 BoardMapper를 이용하면서 자동 주입 대신 @Setter를 통한 주입이 이루어지는 점이다.

- 댓글 등록의 경우에 파라미터로 전달받은 ReplyVO 내에 게시물의 번호가 존재하므로 이를 이용해서 댓글을 추가한다.

- 댓글의 삭제는 전달되는 파라미터가 댓글의 번호인 rno만을 받기 때문에 해당 댓글의 게시물을 알아내는 과정이 필요하다. (게시물의 번호를 받으려면 ReplyController까지 같이 수정해야 한다.)

 

 

 

  • 화면 수정 - list.jsp
    • 게시물의 목록 화면에서 댓글의 숫자가 출력될 수 있도록 수정한다.
<c:forEach items="${list}" var="board">
    <tr>
        <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 value="${board.regdate }" pattern="yyyy-MM-dd" /></td>
        <td><fmt:formatDate value="${board.updateDate }" pattern="yyyy-MM-dd" /></td>
    </tr>
</c:forEach>
cs

 

 


출처 ; 코드로 배우는 스프링 웹 프로젝트[구멍가게 코딩단]

 

'Records > Spring Framework' 카테고리의 다른 글

파일 업로드 상세 처리  (0) 2021.03.28
파일 업로드 방식  (0) 2021.03.28
스프링에서 트랜잭션 관리  (0) 2021.03.22
AOP라는 패러다임  (0) 2021.03.22
Ajax 댓글 처리  (0) 2021.03.18
Comments