본문 바로가기
백엔드(Back-End)/Spring Boot

[sts4-Spring Boot] 16. REST 방식으로 댓글 CRUD

by 기딩 2023. 12. 7.
728x90

게시글 CRUD를 해보았는데, 이번에는 REST 방식으로 댓글을 CRUD 해보자!

 

먼저 데이터베이스에서 댓글 테이블을 만들어야 한다.

 

comment 테이블

 

- 댓글 테이블의 인덱스가 PK, 댓글과 연결되는 게시글 번호는 FK

use board;

create table comment (
    idx INT NOT NULL auto_increment,
    board_idx INT NOT NULL,
    content VARCHAR(3000) NOT NULL,
    writer VARCHAR(20) NOT NULL,
    delete_yn ENUM('Y', 'N') NOT NULL DEFAULT 'N',
    insert_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    update_time DATETIME DEFAULT NULL,
    delete_time DATETIME DEFAULT NULL,
    PRIMARY KEY(idx)
);
ALTER TABLE COMMENT 
ADD CONSTRAINT fk_comment_board_idx foreign key (board_idx) references board(idx);

SELECT *
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = 'board';

 

 

CommentDTO

 

- com.board.domain 패키지에

-데이터베이스에서 가져온 데이터를 전달하고 사용하기 위해 DTO를 생성하자.

 

CommentMapper 인터페이스

 

- DTO와 데이터베이스 간의 매핑을 위해 Mapper 생성

- CRUD 작업을 수행할 메소드 정의

 

- 댓글을 삽입하는 INSERT 쿼리 호출

- 파라미터로 전달받은 댓글 번호(idx)에 해당하는 댓글 상세 내용 조회

- 댓글 수정하는 UPDATE 쿼리 호출

- 댓글 삭제 메서드 -> delete_yn이 'Y'으로

- 특정 게시글에 포함된 댓글 목록 조회하는 SELECT 쿼리 호출

- 특정 게시글에 포함된 댓글 개수 조회하는 SELECT 쿼리 호출

package com.board.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.board.domain.CommentDTO;

@Mapper
public interface CommentMapper {
	public int insertComment(CommentDTO params);
	public CommentDTO selectCommentDetail(Long idx);
	public int updateComment(CommentDTO params);
	public int deleteComment(Long idx);
	public List<CommentDTO> selectCommentList(CommentDTO params);
	public int selectCommentTotalCount(CommentDTO params);
}

 

 

XML Mapper

 

각 CRUD 쿼리를 작성

<?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="com.board.mapper.CommentMapper">

	<sql id="commentColumns">
		idx
		,board_idx
		,content
		,writer
		,delete_yn
		,insert_time
		,update_time
		,delete_time
	</sql>
	
	<insert id="insertComment" parameterType="CommentDTO">
		INSERT INTO comment (
			<include refid="commentColumns" />
		) VALUES (
			#{idx}
			,#{boardIdx}
			,#{content}
			,#{writer}
			,IFNULL(#{deleteYn}, 'N')
			,NOW()
			,NULL
			,NULL
		)
	</insert>
	
    <select id="selectCommentDetail" parameterType="long" resultType="CommentDTO">
        SELECT
            <include refid="commentColumns" />
        FROM
            comment
        WHERE
            delete_yn = 'N'
        AND
            idx = #{idx}
    </select>

    <update id="updateComment" parameterType="CommentDTO">
        UPDATE comment
        SET
            update_time = NOW()
            ,content = #{content}
            ,writer = #{writer}
        WHERE
            idx = #{idx}
    </update>

    <update id="deleteComment" parameterType="long">
        UPDATE	comment
        SET
            delete_yn ='Y'
            ,delete_time = NOW()
        WHERE
            idx = #{idx}
    </update>

    <select id="selectCommentList" parameterType="CommentDTO" resultType="CommentDTO">
        SELECT
            <include refid="commentColumns" />
        FROM
            comment
        WHERE
            delete_yn ='N'
        AND
            board_idx = #{boardIdx}
        ORDER BY
            idx DESC,
            insert_time DESC		
    </select>

    <select id="selectCommentTotalCount" parameterType="CommentDTO" resultType="int">
        SELECT
            COUNT(*)
        FROM
            comment
        WHERE
                delete_yn = 'N'
        AND	board_idx = #{boardIdx}
    </select>
</mapper>

 

 

CommentService 인터페이스

 

쿼리를 사용해야 하니 서비스 인터페이스를 생성

- 일단 등록, 삭제, 조회 기능만 메소드 정의

 

package com.board.service;

import java.util.List;
import com.board.domain.CommentDTO;

public interface CommentService {
	public boolean registerComment(CommentDTO params);
	public boolean deleteComment(Long idx);
	public List<CommentDTO> getCommentList(CommentDTO params);
}

 

 

 

CommentServiceImpl 클래스

 

댓글 서비스 인터페이스의 구현체

- 매퍼의 쿼리를 어떻게 활용할지 구현

 

- Autowired : CommentMapper 빈을 주입

- 게시글 idx가 없으면 댓글 INSERT, 있으면 댓글 UPDATE

- 정상적으로 사용 중인 댓글만 삭제

- 게시글의 댓글이 1개 이상이면 목록 반환 

package com.board.service;

import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.board.domain.CommentDTO;
import com.board.mapper.CommentMapper;

@Service
public class CommentServiceImpl implements CommentService {
	
	@Autowired
	private CommentMapper commentMapper;

	@Override
	public boolean registerComment(CommentDTO params) {
		int queryResult = 0;
		
		if (params.getIdx() == null) {
			queryResult = commentMapper.insertComment(params);
		} else {
			queryResult = commentMapper.updateComment(params);
		}
		
		return (queryResult == 1) ? true : false;
	}

	@Override
	public boolean deleteComment(Long idx) {
		int queryResult = 0;
		
		CommentDTO comment = commentMapper.selectCommentDetail(idx);
		
		if (comment != null && "N".equals(comment.getDeleteYn())) {
			queryResult = commentMapper.deleteComment(idx);
		}
		
		return (queryResult == 1) ? true : false;
	}

	@Override
	public List<CommentDTO> getCommentList(CommentDTO params) {
		List<CommentDTO> commentList = Collections.emptyList();
		
		int commentTotalCount = commentMapper.selectCommentTotalCount(params);
		if (commentTotalCount > 0) {
			commentList = commentMapper.selectCommentList(params);
		}
        
		return commentList;
	}
}

 

CommentTests 클래스

 

- 댓글 CRUD 테스트 위해 test 디렉터리에 댓글테스트 클래스 @SpringBootTest

- commentService 빈을 주입

- 직접 200번 게시글에 댓글 20개 추가 예제

  200번이 아니어도 존재하는 게시글이면 된다. 

- 댓글 번호가 10인 댓글 삭제 예제

- 200번째 글의 댓글 리스트 출력 예제

 

- 각 메소드 Junit Run

package com.board;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.board.domain.CommentDTO;
import com.board.service.CommentService;

@SpringBootTest
public class CommentTests {
	@Autowired
	private CommentService commentService;
	
	@Test
	public void registerComments() {
		int number = 20;
		
		for (int i = 0; i <= number; i++) {
		CommentDTO params = new CommentDTO();
		params.setBoardIdx((long) 200);
		params.setContent(i + "번 댓글을 추가합니다.");
		params.setWriter(i + "번 회원");
		commentService.registerComment(params);
		}
		
		System.out.println("댓글 " + number + "개가 등록되었습니다.");
	}
	
	@Test
	public void deleteComment() {
		commentService.deleteComment((long) 10);
		
		getCommentList();
	}
	
	@Test
	public void getCommentList() {
		CommentDTO params = new CommentDTO();
		params.setBoardIdx((long) 200);
		
		for(CommentDTO comment : commentService.getCommentList(params)) {
			System.out.println("======================");
			System.out.println(comment.getBoardIdx());
			System.out.println(comment.getContent());
			System.out.println(comment.getWriter());
			System.out.println("======================");
		}
	}
}

 

728x90