개발공작소
article thumbnail
728x90

 

오늘은 동영상을 선택했을 때 댓글을 입력하고 댓글을 볼 수 있는 기능을 구현하려고 한다..

우선 기본 유튜브와 비슷하게 UI를 설계(?) 했다.

 

구현 설계화면

 

우선 관련 채널 영상을 우측으로 놔두고, 동영상 아래에 댓글 컴포넌트를 만들어 추가 할 생각이다. 

 

우선 오늘은 댓글을 추가하는 기능에 대해서만 집중하고자, 로그인 같은 기능은 다음시간에 넣어보려고 한다.

로그인 기능 또한 네이버 오픈API를 사용하여 할 생각이다.

 

댓글 같은 경우에는 데이터베이스가 필요하다고 판단되어, Oracle설치 및 기존 프로젝트에 Oracle 및 MyBatis를

연동해주었다.. 각 글을 참조해서 하도록 하자. ( 오라클 설치 ) ( 스프링부트 오라클 및 마이바티스 연동 )

 

그럼 바로 시작해보자.

 

 

1. 댓글 테이블 및 시퀀스 생성

-----------------------------------------------------------------------------------------------------------------------------------

 

우선 댓글을 INSERT, SELECT 할 테이블을 생성해주었다.

 

CREATE TABLE replyTable	(
    COMMENT_ID NUMBER PRIMARY KEY                  -- 댓글 ID
    ,VIDEO_ID NUMBER DEFAULT 0 NOT NULL   		   -- 유튜브영상 ID
    ,CONTENT VARCHAR2(4000)  NOT NULL              -- 댓글
    ,WRITER VARCHAR2(50) NOT NULL                  -- 작성자
    ,DELETE_AT CHAR(1) DEFAULT 'N' NOT NULL        -- 삭제여부 'Y'삭제 'N' 미용
    ,CREATE_DATE DATE DEFAULT SYSDATE NOT NULL     -- 생성일시 
);

 

이제 댓글 작성 및 댓글 조회 관련 기능은 모두 이 테이블을 통해서 하도록 하겠다.. 그리고 댓글ID는 자동으로 1씩

증가하는 시퀀스를 활용하기 위해 시퀀스도 하나 만들어 주었다,

 

CREATE SEQUENCE reply_seq
	INCREMENT BY 1
	START WITH 1
	MINVALUE 1
	MAXVALUE 99999;

 

댓글을 INSERT할때마다 해당 시퀀스를 이용해서 댓글ID를 채워줄 것이다.

 

 

2. 댓글 작성 기능 구현

-----------------------------------------------------------------------------------------------------------------------------------

 

이제 댓글 작성 기능을 구현해보자.. 댓글 기능 또한 컴포넌트화 할 생각이므로 따로 js로 만들었다.

 

reply.js 생성

export default{
	template : `
        <div>
            <div class="input-group" style="margin-top:40px;">
                <input type="text" class="form-control" placeholder="댓글을 입력하여 주십시오." aria-label="Recipient's username with two button addons">
                <button class="btn btn-outline-secondary" type="button">초기화</button>
                <button class="btn btn-outline-secondary" type="button">등록</button>
            </div>
        </div>
	`,
    data () {
        return {

        }
    },
    methods : {

    }
}

 

 

이렇게 틀만 만들어주고, 실제 동영상 팝업창에 지역 컴포넌트로 등록하여 아래와 같이 사용하였다..

 

videoPop.js

import reply from './reply.js'; // 댓글 컴포넌트 import

components : {
    'reply' : reply // reply 지역 컴포넌트 등록
},


<div class="modal-body">
    <div class=video-container style="TEXT-ALIGN: center;width:650px">
        .......
        <reply></reply> // 컴포넌트 등록
        .......
    </div>      
</div>

 

이렇게 코드를 작성하고 화면을 보면 다음과 같아진다..

 

 

이렇게 댓글 컴포넌트를 생성하여 등록하였다. 물론 지금은 아무 기능이 없지만... 이제 저 textarea에 글을 입력하고

[등록] 버튼을 누르면 비동기 통신으로 데이터베이스에 넣는 기능을 구현 해보도록 하자... 

 

 

 

reply.js 댓글 등록 관련 변수 및 함수 추가

export default{
    props: ['item'],
	template : `
        <div>
            <div class="input-group" style="margin-top:40px;">
                <input v-model="content" type="text" class="form-control" placeholder="댓글을 입력하여 주십시오." aria-label="Recipient's username with two button addons">
                <button class="btn btn-outline-secondary" type="button">초기화</button>
                <button class="btn btn-outline-secondary" type="button" @click="insertComment(item)">등록</button>
            </div>
        </div>
	`,
    data () {
        return {
            writer : '',
            content : '',
            videoId : ''
        }
    },
    methods : {
        async insertComment (item) {
            this.writer = 'testUser'; // 임시 등록 사용자ID
            this.videoId = item.id.videoId; // videoId 등록

            let commmentData = {
                'videoId' : this.videoId,
                'writer' : this.writer,
                'content' : this.content
            }

            await fetch('/insertComment.do',{
                method : 'POST',
                headers : {'Content-type' : 'application/json'},
                body : JSON.stringify(commmentData)
            });
            
        }
    }
}

 

댓글 관련변수를 설정해주고, [등록] 버튼을 누르면 insertComment함수를 호출한다.

그리고 commentData라는 객체에 각 데이터를 담아, fetch함수를 이용하여, insertComment.do로 보내준다.

 

IndexController.java

@RequestMapping(value="/insertComment.do", method = RequestMethod.POST)
@ResponseBody
public void insertComment(@RequestBody IndexVO commmentData) {
    indexService.insertComment(commmentData); // data를 받아 service로 보냄
}

 

IndexService.java

@Autowired
IndexMapper indexMapper;

public void insertComment(IndexVO commmentData) {
    indexMapper.insertComment(commmentData);
}

 

IndexMapper.java

public void insertComment(IndexVO commmentData);

 

IndexVO.java

package com.example.demo.service;

import java.io.Serializable;

import org.apache.ibatis.type.Alias;

@Alias("indexVO") // Ailas 설정
public class IndexVO implements Serializable{
    
    private int commentId;
    private String videoId;
    private String content;
    private String writer;
    private String deleteAt;
    private String createDate;

    public int getCommentId() {
        return this.commentId;
    }

    public void setCommentId(int commentId) {
        this.commentId = commentId;
    }

    public String getVideoId() {
        return this.videoId;
    }

    public void setVideoId(String videoId) {
        this.videoId = videoId;
    }

    public String getContent() {
        return this.content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getWriter() {
        return this.writer;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }

    public String getDeleteAt() {
        return this.deleteAt;
    }

    public void setDeleteAt(String deleteAt) {
        this.deleteAt = deleteAt;
    }

    public String getCreateDate() {
        return this.createDate;
    }

    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }

}

 

이렇게 작성을 해준 뒤, 실제 쿼리문을 작성하는 .xml로 보내주면 해당 테이블에 데이터가 들어가는 것을

확인 할 수 있다. ( Alias 설정 등은 링크를 확인 하도록 하자. )

 

IndexMapper.xml

<?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.example.demo.mapper.IndexMapper">
    <insert id="insertComment" parameterType="indexVO">
        insert into replyTable values (reply_seq.NEXTVAL, #{videoId}, #{content}, #{writer}, 'N', SYSDATE)
    </insert>
</mapper>

 

728x90
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!