ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [4-ch17 댓글 처리 ① ] sql 댓글 테이블 생성과 영속 영역 설계 (MyBatis)
    Back-End/Spring Legacy 2022. 9. 1. 12:59

     

    댓글 처리를 위한 영속 영역

     

    댓글 추가하기 위해서 댓글 구조에 맞는 테이블 설계한다. 

     

    --댓글 테이블 설계
    
    create table tbl_reply (
      rno number(10,0), -- 댓글 번호
      bno number(10,0) not null, -- 어떤 게시글인지 게시글 번호
      reply varchar2(1000) not null, --댓글 내용
      replyer varchar2(50) not null,  --댓글 작성자
      replyDate date default sysdate,  --댓글 작성일
      updateDate date default sysdate --댓글 수정일
    );
    
    select * from tbl_reply;
    
    create sequence seq_reply;
    
    --식별키(PK) 지정
    alter table tbl_reply add constraint pk_reply primary key (rno);
    
    --왜래키(FK) 지정
    alter table tbl_reply  add constraint fk_reply_board  
    foreign key (bno)  references  tbl_board (bno);

     

    테이블 이름은 tbl_reply로 지정하고 댓글 번호를 위해 시퀀스 seq_reply를 생성해준다. 프라이머리키로 rno를 지정해주고 tbl_reply의 bno 값을 tbl_board bno값의 외래키로 지정한다. 

     

     

     

    1. ReplyVO

     

    <ReplyVO>

    package org.zerock.domain;
    
    import java.util.Date;
    
    import lombok.Data;
    
    @Data
    public class ReplyVO {
    	
    	private Long rno; //댓글 번호
    	private Long bno; //댓글의 해당 게시글 번호
    	private String reply; //댓글 내용
    	private String replyer; //댓글 작성자
    	private Date replyDate; //작성일
    	private Date updateDate; //수정일
    	
    	
    
    }

     

     

    2. ReplyMapper 인터페이스 , xml 작성

     

    댓글에 대한 처리 역시 화면상에서 페이지 처리가 필요할 수 있으므로 이전 게시판에서 작성해둔 Criteria를 이용해 처리하도록 한다. 실제 SQL은 'src/main/resources' 폴더 아래 ReplyMapper.xml 파일을 작성해서 처리한다. 

     

    <ReplyMapper.java 인터페이스>

    package org.zerock.mapper;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.Param;
    import org.zerock.domain.Criteria;
    import org.zerock.domain.ReplyVO;
    
    public interface ReplyMapper {
    	
    	public int insert(ReplyVO vo); //댓글 추가
    	
    	public ReplyVO read(Long rno); //댓글 조회
    	
    	public int delete(Long rno); //댓글 삭제
    	
    	public int update(ReplyVO vo); //댓글 수정
    	
    	public List<ReplyVO> getListWithPaging(
    			@Param("cri") Criteria cri, @Param("bno") Long bno);
    	
    
    }

     

     

    <ReplyMapper.xml>

     

    XML에서는 tbl_reply 테이블에 필요한 SQL을 작성한다. XML을 작성할 때는 항상 namespace에 주의해서 작성한다.

     

    <?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="org.zerock.mapper.ReplyMapper">
    
    	<insert id="insert">
    		insert into tbl_reply(rno, bno, reply, replyer)
    		values (seq_reply.nextval, #{bno}, #{reply},#{replyer})
    	</insert>
    	
    	<select id="read" resultType="org.zerock.domain.ReplyVO">
    		select * from tbl_reply where rno =#{rno}
    	</select>
    	
    	<delete id="delete">
    		delete from tbl_reply where rno =#{rno}
    	
    	</delete>
    	
    	<update id="update">
    		update tbl_reply
    		set reply=#{reply}, updatedate = sysdate where rno = #{rno} 
    	</update>
    	
    	<!-- 게시글 번호에 해당하는 댓글 조회 -->
    	<select id="getListWithPaging" resultType="org.zerock.domain.ReplyVO">
    		select rno, bno, reply, replyer, replyDate, updatedate
    		 from tbl_reply where bno =#{bno}
    		 order by rno asc
    	</select>
    	
    </mapper>

     

     

    위에 첨부한 인터페이스와 xml을 가지고 테스트 코드를 만들어서 xml 영속계층에서 데이터의 CRUD가 잘 일어나는지 확인해보려고 한다. 

     

     

     

    <2-1 등록 (create) ReplyMapperTests >

     

    package org.zerock.mapper;
    
    import java.util.List;
    import java.util.stream.IntStream;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.zerock.domain.Criteria;
    import org.zerock.domain.ReplyVO;
    
    import lombok.Setter;
    import lombok.extern.log4j.Log4j2;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    @ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
    						"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
    @Log4j2
    public class ReplayMapperTests {
    	
    	
    	private Long[] bnoArr = {150L,149L,148L,147L,146L};
    	
    	@Setter(onMethod_ = @Autowired)
    	private ReplyMapper mapper;
    	
    	@Test
    	public void testMapper() {
    		log.info(mapper);
    	}
    
    	@Test
    	public void testCreate() {
    		IntStream.rangeClosed(1, 10).forEach(i -> {
    			
    			ReplyVO vo = new ReplyVO();
    			vo.setBno(bnoArr[i%5]);
    			vo.setReply("댓글테스트"+i);
    			vo.setReplyer("replyer"+i);
    			
    			mapper.insert(vo);
    			
    		});
    	}
        }

     

     

    ReplyMapperTests 내부의 bnoArr은 게시물 번호의 일부로 실제 데이터베이스에 있는 번호여야만 한다. (PK와 FK의 관계로 묶여있기 때문에) 테스트가 정상적으로 실행되는지 최종적으로 데이터베이스의 tbl_reply의 상태를 확인한다. 

     

     

     

    1번부터 10번까지 댓글이 작성된 걸 확인할 수 있다. 

     

     


     

     

     

    <2-2 조회 (read) ReplyMapperTests >

     

    @Test
    public void testRead() {
    
        ReplyVO vo = mapper.read(5L);
        log.info(vo);
    
    }

     

    테스트 결과로 5번이 조회되는지 확인한다. 

     

     

     


    <2-3 삭제 (delete) ReplyMapperTests >

     

    특정 댓글의 삭제는 댓글의 번호(rno)만으로 처리가 가능하다.  1번 댓글이 삭제되었나 확인

     

    @Test
    public void testDelete() {
    
        Long targetRno = 1L;
        mapper.delete(targetRno);
        log.info("delete......"+ targetRno);
    
    }

     

     


     

     

    <2-4 수정 (update) ReplyMapperTests >

     

    댓글의 수정은 현재 tbl_reply 테이블 구조에서는 댓글의 내용(reply) 과 최종 수정시간(updateDate)을 수정한다. 

     

    @Test
    public void testUpdate() {
    
    //		ReplyVO vo = new ReplyVO();
    //		vo.setRno(2L);
    //		vo.setReply("변경된 댓글입니다.");
    //		mapper.update(vo);
    
        Long targetRno = 10L;
        ReplyVO vo2 = mapper.read(targetRno);
        vo2.setReply("변경된 댓글입니다.22");
        int count = mapper.update(vo2);
        log.info("update count : " + count);
    }

     


    <2-5 댓글 목록 조회 (getListWithPaging) ReplyMapperTests >

     

    @Test
    public void testList() {
        Criteria cri = new Criteria();
        List<ReplyVO> replies = mapper.getListWithPaging(cri, bnoArr[0]);
        replies.forEach(reply -> log.info(reply));
    }

     

    댓글의 목록과 페이징 처리는 기존의 게시물 페이징 처리와 유사하지만, 추가적으로 특정한 게시물의 댓글만을 대상으로 하기 때문에 게시물의 번호가 필요하게 된다. 

     

     

    MyBatis는 두 개 이상의 데이터를 파라미터로 전달하기 위해서 3가지 방식이 있다. 

    1. 별도의 객체로 구성
    2. Map을 이용
    3. @Param을 이용해 이름을 사용

     

    여러 방식 중 가장 간단한 @Param을 사용해 코드를 작성하였다. @Param의 속성값은 MyBatis에서 SQL을 이용할 때 '#{}'의 이름으로 사용이 가능하다. 

     

    <!-- 게시글 번호에 해당하는 댓글 조회 -->
    <select id="getListWithPaging" resultType="org.zerock.domain.ReplyVO">
        select rno, bno, reply, replyer, replyDate, updatedate
         from tbl_reply where bno =#{bno}
         order by rno asc
    </select>

     

     

     

     

    반응형

    댓글

Designed by Tistory.