-
[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>
반응형'Back-End > Spring Legacy' 카테고리의 다른 글
[4 -ch17 댓글 처리 ② ] 서비스 영역과 Controller 처리 (@RequestBody, @PathVariable, consumes, produces ) (0) 2022.09.01 [Spring REST] @RequestBody와 @RequestParam 차이 (0) 2022.09.01 [4-ch16 REST 방식] @RestController, ResponseEntity, @RequestParam , 어노테이션과 JSON 알아보기 (0) 2022.08.31 [3-ch15 Spring 게시판] 검색 조건 처리 (0) 2022.08.29 [3-ch15 Spring ] MyBatis의 동적 태그 ( if, choose, trim)와 LIKE 사용 방법 (0) 2022.08.29