[작성일: 2023. 05. 13]
Reply 목록 구현
- 기존 게시물 페이징 처리 + 특정 게시물 번호
- MyBatis는 두 개 이상의 데이터를 파라미터로 전달하기 위해서 별도 객체를 구성하거나, Map을 이용하거나, @Param을 이용함.
- 가장 간단한 방식인 @Param을 이용하여 구현하면 속성값은 MyBatis에서 #{}으로 사용이 가능함. (과거)
ReplyMapper에 getListWithPaging 구현
@Mapper
public interface ReplyMapper {
...
// 댓글 목록
public List<ReplyVO> getListWithPaging(@Param("cri") Criteria cir, @Param("bno") Long bno);
}
ReplyMapper.xml
<select id="getListWithPaging" resultType="replyVO">
SELECT RNO, BNO, REPLY, REPLIER, REPLYDATE, UPDATEDATE
FROM TBL_REPLY
WHERE BNO = #{bno}
ORDER BY RNO DESC
LIMIT #{cri.limit} OFFSET #{cri.offset}
</select>
ReplyMapperTest
@Test
public void testList() {
Criteria cri = new Criteria();
List<ReplyVO> replies = mapper.getListWithPaging(cri, arBno[1]);
log.info("reply list-------------------");
replies.forEach(reply -> log.info(reply.toString()));
}
ReplyDAO 생성 후 각 메서드 구현
@Repository
@RequiredArgsConstructor
@Slf4j
public class ReplyDAO {
private ReplyMapper mapper;
public int register(ReplyVO reply) {
log.info("register...!" + reply);
return mapper.insert(reply);
}
public ReplyVO get(Long rno) {
log.info("get...!" + rno);
return mapper.read(rno);
}
public int modify(ReplyVO reply) {
log.info("modify...!" + reply);
return mapper.update(reply);
}
public int remove(Long rno) {
log.info("remove...!" + rno);
return mapper.delete(rno);
}
public List<ReplyVO> getList(Criteria cri, Long bno) {
log.info("get Reply List...! " + bno);
cri.setParam();
return mapper.getListWithPaging(cri, bno);
}
}
ReplyDAOTest 수행
@SpringBootTest
@Slf4j
@RunWith( SpringJUnit4ClassRunner.class )
public class ReplyDAOTest {
@Autowired
private ReplyDAO replyDAO;
private Long[] arBno = {7L, 12L, 36L, 38L, 40L};
@Test
public void testRegister() {
// 5개의 게시글에 2개씩 댓글을 달아봅시다.
IntStream.rangeClosed(1, 10).forEach(i -> {
ReplyVO reply = new ReplyVO();
reply.setBno(arBno[i%5]);
reply.setReply("댓글 자동 생성" + i);
reply.setReplier("Robot.DAO" + i);
replyDAO.register(reply);
});
}
@Test
public void testRead() {
Long targetRno = 2L;
ReplyVO reply = replyDAO.get(targetRno);
log.info("replyDAO - get ------------------");
log.info(reply.toString());
}
@Test
public void testDelete() {
Long targetRno = 10000L;
int deleteCount = replyDAO.remove(targetRno);
log.info("replyDAO - delete -----------------------");
log.info("delete Count: " + deleteCount);
}
@Test
public void testUpdate() {
Long targetRno = 9L;
ReplyVO reply = replyDAO.get(targetRno);
reply.setReply("업데이트 두 번째");
int updateCount = replyDAO.modify(reply);
log.info("replyDAO - update -----------------------");
log.info("update Count: " + updateCount);
}
@Test
public void testList() {
Criteria cri = new Criteria();
List<ReplyVO> replies = replyDAO.getList(cri, arBno[1]);
log.info("replyDAO - letList ---------------");
replies.forEach(reply -> log.info(reply.toString()));
}
}
ReplySerivce Interface 생성
@Service
public interface ReplyService {
public int register(ReplyVO reply);
public ReplyVO get(Long rno);
public int modify(ReplyVO reply);
public int remove(Long rno);
public List<ReplyVO> getList(Criteria cri, Long bno);
}
ReplyServiceImp 인터페이스 구현
@Service
@Slf4j
@RequiredArgsConstructor
public class ReplyServiceImp implements ReplyService {
@Autowired
private ReplyDAO replyDAO;
@Override
public int register(ReplyVO reply) {
log.info("register..........." + reply);
return replyDAO.register(reply);
}
@Override
public ReplyVO get(Long rno) {
log.info("get..........." + rno);
return replyDAO.get(rno);
}
@Override
public int modify(ReplyVO reply) {
log.info("modify..........." + reply);
return replyDAO.modify(reply);
}
@Override
public int remove(Long rno) {
log.info("remove..........." + rno);
return replyDAO.remove(rno);
}
@Override
public List<ReplyVO> getList(Criteria cri, Long bno) {
log.info("getList..........." + bno);
return replyDAO.getList(cri, bno);
}
}
ReplyService 테스트 수행
Presentation Tier 구현(Controller)
- JSON 데이터로 전송받은 후 REST 형식으로 사용
- REST(Representation State Interface)
- 하나의 URI는 하나의 고유한 리소스를 대표하도록 설계된다.
- /board/123 : 게시물 중 123번
pom.xml 추가
- 추가 후 maven update 수행
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
Controller 생성
- ReplyController
- @RestController
- ViewResolver를 사용하지 않고 리턴 값을 그대로 데이터로 사용함. 내부 메서드는 REST 방식으로만 사용 가능함.
- RestController 속성 사용으로 데이터 통신만 하도록 설정
- 댓글 등록
- 브라우저에서 JSON 타입으로 데이터를 전송하고, 서버에서는 댓글 처리 결과에 따라 문자열로 결과를 리턴
- consume: Ajax를 통해 전달받은 데이터의 타입
- produces: Ajax의 success:function(result)의 result에 전달할 데이터의 타입
- @ResponseBody
- @Controller에서 Body를 응답하기 위해(viewResolver를 가지 않게 하기 위해) 사용
- 서버의 상태 코드, 응답 메시지 등을 받을 수 있는 타입
- ReplyVO reply로 전송 데이터를 ReplyVO 타입 consumes, produces 속성 설정
- @RequestBody
- JSON 데이터를 ReplyVO 타입으로 변환하도록 지정
- 문자열 전송 시 한글이 깨지지 않게 하기 위해 text/plain; charset=utf-8 사용
@RestController
// ViewResolver를 사용하지 않고 리턴 값을 그대로 데이터로 사용
// 내부 메서드는 REST 방식으로만 사용 가능함.
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/replies/*")
public class ReplyController {
private final ReplyService replyService;
@PostMapping(value="/new", consumes="application/json", produces="text/plain; charset=utf-8")
public ResponseEntity<String> create(@RequestBody ReplyVO reply) throws UnsupportedEncodingException {
int insertCount = 0;
log.info("--------------------------");
log.info(reply.toString());
insertCount = replyService.register(reply);
if(insertCount == 1) {
return new ResponseEntity<>(new String("댓글 등록 성공".getBytes(), "UTF-8"), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Chrome 확장 프로그램 설치
- Talend API Tester - Free Edition
- Method : POST
- Scheme: http://localhost 주소 / replies/new
- Headers : Content-Type을 application/json
- Body : {"bno":3, "reply":"Yayaya", "replier":"merong"}
- send 클릭 후 200, 댓글 등록 완료 확인
- 오류가 난다면 https로 보낸 것이 아닌지 주소 확인
🐣 해당 게시글은 입문 개발자가 요약/정리한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.