1. 테이블 설계
- rno : 댓글 번호 - (10,0): 숫자 10자리까지, 소숫점 자리 0자리까지 들어갈 수 있다
- bno: 게시글 번호
- reply : 댓글(내용)
- tbl_reply 테이블의 bno는 tbl_board의 bno를 참조함 (댓글을 달려면 특정 게시물의 번호가 필요!)
2. 자바빈 클래스 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package org.hw.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; } | cs |
3. 인터페이스 생성과 XML 처리
1 2 3 4 5 | package org.hw.mapper; public interface ReplyMapper { } | cs |
1 2 3 4 5 6 7 8 | <?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.hw.mapper.ReplyMapper"> </mapper> | cs |
tbl_reply가 tbl_board 테이블의 bno 값과 정확히 일치해야 하므로 bno 몇 개를 확인해두는 작업
4. 테스트 클래스 작성
1) ReplyMapper 객체를 정상적으로 사용 가능한지 확인하는 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package org.hw.mapper; 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.SpringRunner; import lombok.Setter; import lombok.extern.log4j.Log4j; @RunWith(SpringRunner.class) @ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml") @Log4j public class ReplyMapperTest { @Setter(onMethod_ = @Autowired) private ReplyMapper mapper; @Test public void testMapper() { log.info(mapper); } } | cs |
정상 작동 확인!
5. CRUD 작업
1) 등록 (create)
1 2 3 4 5 6 7 8 9 | package org.hw.mapper; import org.hw.domain.ReplyVO; public interface ReplyMapper { public int insert(ReplyVO vo); } | cs |
▲ ReplyMapper 인터페이스
1 2 3 4 5 6 7 8 9 10 11 12 | <?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.hw.mapper.ReplyMapper"> <insert id="insert"> insert into tbl_reply (rno, bno, reply, replyer) values (seq_reply.nextval, #{bno}, #{reply}, #{replyer}) </insert> </mapper> | cs |
▲ ReplyMapper.xml
✨ 테스트 코드 작성
✨ 실행 결과
2) 조회 (read)
▲ ReplyMapper 인터페이스
▲ ReplyMapper.xml
✨ 테스트 코드 작성
3) 삭제 (delete)
▲ ReplyMapper 인터페이스
▲ ReplyMapper.xml
✨ 테스트 코드 작성
✨ 실행 결과
4) 수정 (update)
- 댓글의 내용과 updateDate를 수정함
▲ ReplyMapper 인터페이스
▲ ReplyMapper.xml
✨ 테스트 코드 작성
✨ 실행 결과
6. 특정 게시글의 댓글 가져오기 - @Param 어노테이션 사용
특정한 게시물의 댓글들만을 가져오기 위해선 추가로 게시물의 번호가 필요하다.
MyBatis의 두 개 이상의 데이터를 파라미터로 전달하기 위한 방식으로는 별도의 객체로 구성, Map을 이용하는 방식, @Param을 이용해서 이름을 사용하는 방식이 있는데 @Param을 이용해서 게시글의 댓글을 가져오는 작업을 진행함.
@Param 의 속성값은 MyBatis에서 SQL을 이용할 때 ' #{ } ' 의 이름으로 사용 가능
- 페이징 처리는 기존과 동일하게 Criteria 이용
- 추가적으로 해당 게시물의 번호는 파라미터를 전달하도록 ReplyMapper 구성하기
▲ ReplyMapper 인터페이스
- cri 라는 이름으로 Criteria 객체 저장
- bno라는 이름으로 bno 저장
▲ ReplyMapper.xml
✨ 테스트 코드 작성
✨ 실행 결과
7. 서비스 영역과 Controller 처리
7-1) 서비스 인터페이스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package org.hw.service; import java.util.List; import org.hw.domain.Criteria; import org.hw.domain.ReplyVO; public interface ReplyService { //등록 public int register(ReplyVO vo); //조회 public ReplyVO get(Long rno); //수정 public int modify(ReplyVO vo); //삭제 public int remove(Long rno); //특정 게시글의 댓글 리스트 가져오기 public List<ReplyVO> getList(Criteria cri, Long bno); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | package org.hw.service; import java.util.List; import org.hw.domain.Criteria; import org.hw.domain.ReplyVO; import org.hw.mapper.ReplyMapper; //import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import lombok.AllArgsConstructor; //import lombok.Setter; import lombok.extern.log4j.Log4j; @Service @Log4j @AllArgsConstructor public class ReplyServiceImpl implements ReplyService { //@Setter(onMethod_ = @Autowired) //스프링 5 사용으로 인한 @AllArgsConstructor: 생성자와 자동주입 private ReplyMapper mapper; @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); } @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); } } | cs |
- 스프링 4.3 이상부터 @Setter (onMethod_ = @Autowired 대신 @AllArgsConstructor 어노테이션을 이용하여 생성자와 자동주입을 이용 할 수 있다.
7-2) 컨트롤러 설계
- @RestController 어노테이션을 이용해 설계
- 다음과 같은 URL을 기준으로 동작 할 수 있게 함
작업 | URL | HTTP 전송 방식 |
등록 | /replies/new | POST |
조회 | /replies/:rno | GET |
삭제 | /replies/:rno | DELETE |
수정 | /replies/:rno | PUT & PATHCH |
페이지 | /replies/pages/:bno/:page | GET |
- 똑같은 URL에 전송 방식만 다르게 설계
- REST 방식으로 동작하는 URL을 설계할 때는 PK만으로 조회, 수정, 삭제가 가능하기 때문에 PK를 기준으로 작성하는 것이 좋다.
- 댓글의 목록은 PK를 사용할 수 없기 때문에 파라미터로 필요한 게시물의 번호(bno)와 페이지 번호(page) 정보들을 URL에서 사용하는 방식 사용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package org.hw.controller; import java.util.List; import org.hw.domain.Criteria; import org.hw.domain.ReplyVO; import org.hw.service.ReplyServiceImpl; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import lombok.AllArgsConstructor; import lombok.extern.log4j.Log4j; @RequestMapping("/replies/") @RestController @Log4j @AllArgsConstructor public class ReplyController { //ReplyServiceImpl 객체 주입 private ReplyServiceImpl service; } | cs |
7-2-1) 댓글 등록 작업과 테스트
- consumes = json 타입을 받음
- produces = text로 만듦
✨ 테스트 (Yet Another REST Client 사용)
bno, reply, replyer 값을 입력 하여 전송
전송 결과
로그 확인!
작성한 댓글이 데이터베이스에도 정상적으로 추가됨
7-2-2) 특정 게시물의 댓글 목록 확인
✨ 테스트
글번호 77846의 1 페이지에 있는 댓글들 요청
데이터베이스와 똑같은 결과 확인
로그 확인
7-2-3) 댓글 조회와 삭제
✨ 테스트
1) 댓글 조회
댓글번호 25번 댓글 조회
결과
데이터 베이스의 동일한 결과 확인
2) 댓글 삭제
25번 댓글 삭제 확인
💡 존재하지 않는 rno 값을 전송하면 500 오류 발생함
7-2-3) 댓글 수정
✨ 테스트
9번 댓글 수정 요청
결과
로그 확인
'Dev > Spring' 카테고리의 다른 글
@PathVariable 리다이렉트 구현하기 (0) | 2023.04.01 |
---|---|
@PathVariable 적용기 (0) | 2023.04.01 |
스프링 5 @Controller 구현과 테스트 (0) | 2022.11.01 |
스프링 5 @Service 서비스 구현과 테스트 (0) | 2022.10.31 |
스프링MVC 5.0.7 버전 설정 및 테스트 (0) | 2022.10.28 |
댓글