Backend/Spring

[Spring] 댓글 테이블, 클래스 구조 생성

Deeb 2022. 1. 19. 15:44

댓글 & 대댓글 기본 구조

댓글 순서는 sns는 최신순, 커뮤니티는 오래된순으로 정렬되어있는 모습을 볼 수 있다

 

계층형 구조를 만드는게 어려운데 SQL 만드는게 상당히 어려운데 다행히 Oracle DBMS는 계층형 구조를 만드는 방법을 제공하고있다.

 


1.  댓글 테이블 생성

-- 댓글 테이블           
CREATE TABLE "REPLY" (
   "REPLY_NO"   NUMBER      PRIMARY KEY,
   "REPLY_CONTENT"   VARCHAR2(1000)      NOT NULL,
   "REPLY_CREATE_DT"   DATE   DEFAULT SYSDATE   NOT NULL,
   "BOARD_NO"   NUMBER   REFERENCES BOARD,
   "MEMBER_NO"   NUMBER   REFERENCES MEMBER,
   "STATUS_CD"   NUMBER   DEFAULT 1 REFERENCES STATUS,
    "PARENT_REPLY_NO" NUMBER REFERENCES REPLY
);

COMMENT ON COLUMN "REPLY"."REPLY_NO" IS '댓글 번호';
COMMENT ON COLUMN "REPLY"."REPLY_CONTENT" IS '댓글 내용';
COMMENT ON COLUMN "REPLY"."REPLY_CREATE_DT" IS '댓글 작성일';
COMMENT ON COLUMN "REPLY"."BOARD_NO" IS '게시글 번호';
COMMENT ON COLUMN "REPLY"."MEMBER_NO" IS '회원 번호';
COMMENT ON COLUMN "REPLY"."STATUS_CD" IS '상태 코드';           
COMMENT ON COLUMN "REPLY"."PARENT_REPLY_NO" IS '부모 댓글 번호';        

CREATE SEQUENCE SEQ_REPLY_NO; -- 댓글 번호 시퀀스

--DROP SEQUENCE SEQ_REPLY_NO;

COMMIT;

 

1-1) 샘플데이터 insert

- 댓글 샘플 데이터 넣을 게시글 번호, 회원 번호 정해서 넣기 

INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1', SYSDATE, 511, 1, 1, NULL);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식1', SYSDATE, 511, 1, 1, 1);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식2', SYSDATE, 511, 1, 1, 1);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식3', SYSDATE, 511, 1, 1, 1);

INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모2', SYSDATE, 511, 1, 1, NULL);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모3', SYSDATE, 511, 1, 1, NULL);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모4', SYSDATE, 511, 1, 1, NULL);

INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모2-자식1', SYSDATE, 511, 1, 1, 5);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모2-자식2', SYSDATE, 511, 1, 1, 5);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모2-자식3', SYSDATE, 511, 1, 1, 5);


INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식3-손자1', SYSDATE, 511, 1, 1, 4);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식3-손자2', SYSDATE, 511, 1, 1, 4);
INSERT INTO REPLY VALUES(SEQ_REPLY_NO.NEXTVAL, '부모1-자식3-손자3', SYSDATE, 511, 1, 1, 4);

 

1-2) 특정 게시글에서 삭제되지 않은 댓글 목록을 계층형으로 조회

SELECT LEVEL, R.* 
FROM (SELECT REPLY_NO, REPLY_CONTENT,  TO_CHAR(REPLY_CREATE_DT, 'YYYY"년" MM"월" DD"일" HH24"시" MI"분" SS"초"') REPLY_CREATE_DT,
    BOARD_NO, REPLY.STATUS_CD, PARENT_REPLY_NO, MEMBER_NO, MEMBER_NM 
    FROM REPLY
    JOIN MEMBER USING(MEMBER_NO)
    WHERE BOARD_NO = 511 
    AND REPLY.STATUS_CD = 1) R
START WITH PARENT_REPLY_NO IS NULL
CONNECT BY PRIOR REPLY_NO = PARENT_REPLY_NO
ORDER SIBLINGS BY REPLY_NO;

 


계층 구조를 위한 클래스 구조 생성

-  vo를 가지고 데이터를 삽입할때 , db에서 조회할때도 가져오기 위해 resultMap 생성, 별칭 등록

 

1. mybatis-config

- 별칭, xml 연결

<typeAliases>
    <typeAlias type="edu.kh.fin.board.model.vo.Reply" alias="Reply"/>
</typeAliases>

<mappers>
    <mapper resource="/mappers/reply-mapper.xml"/>
</mappers>

 

2. reply-mapper

- namespace, resultMap 생성

<mapper namespace="replyMapper">

    <resultMap type="Reply" id="reply_rm">
        <id property="replyNo" column="REPLY_NO" />

        <result property="replyContent" column="REPLY_CONTENT" />
        <result property="replyCreateDate" column="REPLY_CREATE_DT" />
        <result property="memberNo" column="MEMBER_NO" />
        <result property="boardNo" column="BOARD_NO" />
        <result property="statusCode" column="STATUS_CD" />
        <result property="memberName" column="MEMBER_NM" />
        <result property="parentReplyNo" column="PARENT_REPLY_NO" />
    </resultMap>
    
</mapper>

 

3. 클래스 생성

reply도 board의 일부니 같은 폴더에 생성

- 컨트롤러, 서비스, 서비스임플, dao 

- service Impl은 service 인터페이스 구현 하기 : implements ReplyService

 

4. method 생성

조회 / 삽입 / 수정 / 삭제

- 댓글은 ajax로 구현이 된다

 

컨트롤러에서 return 은 값이 아니라 주소, 경로로만 보내진다 

그런데 @ResponseBody 가 붙으면 주소로 요청을 해도 특정 값만 얻어온다 (restful)


reply.jsp

대댓글은 padding-left를 주어서 들여쓰기한것처럼 만들기

/* 자식 댓글를 안쪽으로 조금 들여 넣기 */
.child-reply{ padding-left: 60px;}

/* 대댓글 내용 작성 영역*/
.replyInsertContent{
	width:100%; margin-top:10px; resize:none;
}

 

반응형