프로젝트/Staffriends 프로젝트

[Staffriends 프로젝트] (2) 게시판 CRUD 구현하기 - 1. 글쓰기

sungw00 2023. 5. 22. 17:33
728x90

글쓰기

1. 게시판 CRUD를 구현하기 위해 BoardVO 클래스를 작성 & board 테이블 생성

package board.vo;

import lombok.Data;

@Data
public class BoardVo {
    private int boardIdx; // 게시글 번호
    private String title; // 제목
    private String contents; // 내용
    private int hitCnt; // 조회수
    private String username; // 작성자 id
    private String nickname; // 작성자 닉네임
    private String createdDateTime; // 작성일
    private String updaterId; // 수정자
    private String updatedDateTime; // 수정일
    private int replyCount; // 댓글 갯수
    private String deletedYn; // 삭제 여부
}
CREATE TABLE board
(
    `board_idx`         int(10)         NOT NULL    AUTO_INCREMENT COMMENT '게시글 번호',
    `title`             varchar(300)    NOT NULL    COMMENT '제목',
    `contents`          text            NOT NULL    COMMENT '내용',
    `hit_cnt`           smallint(10)    NOT NULL    DEFAULT 0 COMMENT '조회수',
    `created_datetime`  datetime        NOT NULL    COMMENT '작성 일자',
    `username`          varchar(50)     NOT NULL    COMMENT '작성 회원 id',
    `updated_datetime`  datetime        NULL        COMMENT '수정 일자',
    `updater_id`        varchar(50)     NULL        COMMENT '수정 회원 id',
    `deleted_yn`        char(1)         NOT NULL    DEFAULT 'N' COMMENT '삭제 여부',
    `reply_count`       int             NULL        DEFAULT 0 COMMENT '댓글 갯수',
     PRIMARY KEY (board_idx)
);

-- Foreign Key 설정 SQL - board(creator_id) -> user(username)
ALTER TABLE board
    ADD CONSTRAINT user_board_fk FOREIGN KEY (username)
        REFERENCES user (username) ON DELETE RESTRICT ON UPDATE RESTRICT;

UserVO와 마찬가지로 getter, setter, toString 등의 메서드를 자동으로 생성해주는 롬복 라이브러리를 사용했다. 

게시글 번호(board_idx): MariaDB의 AUTO_INCREMENT 기능을 사용하여 자동으로 1씩 증가되도록 하였고,

조회수(hit_cnt): 기본값은 0으로 하고, 게시글을 클릭할 때마다 1씩 증가하도록 할 것이다.

작성 일자(created_datetime): datetime 형식으로 SQL문 작성 시 now() 함수를 이용해 추가해줄 것이다.

작성 회원(username): 작성 회원의 id로, SQL문을 통해 DB에 insert 시켜줄 것이다.

수정자(updater_id)와 수정일(updated_datetime)은 추가하고싶지 않다면 추가하지 않아도 문제가 없다.

댓글 갯수(reply_count): 게시판에 달린 댓글의 갯수를 카운트하기 위해 추가했고, 이 댓글의 갯수는 게시글 목록 페이지에서 보여줄 것이다.

 

롬복을 사용하기 위해 IntelliJ -> Settings -> Plugins에서 lombok을 설치해주었다.

 

2. BoardController 작성

게시판 기능은 기본적으로 네 가지 기능을 떠올릴 수 있다.

  1. 글쓰기(Create)
  2. 글읽기(Read)
  3. 글수정(Update)
  4. 글삭제(Delete)

글쓰기를 담당하는 컨트롤러는 다음과 같다.

package board.controller;

import board.vo.BoardVo;
import board.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

@Controller
public class BoardController {

    @Autowired
    private BoardService boardService;

    @RequestMapping("/board/boardWrite") // 글 작성 페이지
    public String boardWrite() {
        return "/board/boardWrite";
    }

    @RequestMapping("/board/insertBoard") // 글 작성 로직
    public String insertBoard(BoardVo boardVo, @RequestParam String username, @RequestParam String nickname) throws Exception {
        boardVo.setUsername(username);
        boardVo.setNickname(nickname);
        boardService.insertBoard(boardVo);
        return "redirect:/board";
    }
  1. /board/boardWrite로 받은 요청을 /board/boardWrite.jsp(글쓰기 페이지)로 반환해준다.
  2. 이후에 boardWrite.jsp에서 글을 작성하면 /board/insertBoard로 요청하여 게시글 정보작성자의 정보를 DB에 insert한 후 게시글 목록으로 이동하도록 한다.

 

3. BoardService, BoardServiceImpl, BoardMapper 작성

BoardService.java

package board.service;

import board.vo.BoardVo;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public interface BoardService {
    void insertBoard(BoardVo boardVo) throws Exception;
}

BoardServiceImpl.java

package board.service;

import board.vo.BoardVo;
import board.mapper.BoardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BoardServiceImpl implements BoardService {

    @Autowired
    private BoardMapper boardMapper;

    @Override
    public void insertBoard(BoardVo boardVo) throws Exception { // 글쓰기
        boardMapper.insertBoard(boardVo);
    }
}

BoardMapper.java

package board.mapper;

import board.vo.BoardVo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
import java.util.Map;

@Mapper
public interface BoardMapper {
    void insertBoard(BoardVo boardVo) throws Exception;
}

 

4. /board/boardWrite.jsp 생성

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="../layout/header.jsp"%>
<c:if test="${signIn == null}"><c:redirect url="http://staffriends.duckdns.org/user/needLogin"/></c:if>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>글쓰기</title>
    <style>
      .ck-editor__editable { height: 1000px; }
      .ck-content { font-size: 12px; }
      .cke_chrome {max-width: 90%; height: auto; margin: auto; }
      .textarea {width: 100%; border: none; resize: none; height: 3.1rem;}
    </style>
</head>
<body class="center-div">

    <div class="container justify-content-center">
    <h2 style="text-align: center; margin-top: 30px; margin-bottom: 70px; font-family: KakaoBold;">글쓰기</h2>
    <form id="frm" name="frm" method="post">
      <table style="margin-left:auto;margin-right:auto;">
        <tr>
          <td>
              <textarea class="textarea" id="title" name="title" placeholder="제목을 입력해주세요." style="font-size: 30px"></textarea>
              <hr style="margin-top: 0;"/>
          </td>
        </tr>
        <tr>
          <td colspan="2">
            <textarea class="form-control" id="contents" name="contents"></textarea>
            <script>
                writeEditor();
            </script>
          </td>
        </tr>
        <input type="hidden" value="${signIn.username}" name="username" id="username">
        <input type="hidden" value="${signIn.nickname}" name="nickname" id="nickname">
      </table>
    </form>
    <h5 style="text-align: center"><button class="btn btn-success" id="save" style="margin-top: 20px; margin-bottom: 20px;">글 작성 완료</button></h5>
      <script>
          insertBoard();
      </script>
    </div>

</body>
<%@ include file="../layout/footer.jsp"%>
</html>

hidden 값으로 username과 nickname 값을 넘겨주고, 컨트롤러에서는 이 두 값을 받아 setUsername과 setNickname 메서드로 값을 지정한 뒤 DB에 insert 한다.

글쓰기 페이지에는 CKEditor4를 적용했으며, CKEditor4는 아래 링크에서 다운로드하거나 CDN 링크를 얻을 수 있다.

https://ckeditor.com/ckeditor-4/download/

 

CKEditor 4 - Download Latest Version

Download a ready-to-use Latest Version of CKEditor 4 package.

ckeditor.com

 

4. js/board.js 작성

function insertBoard() {
    document.getElementById("save").onclick = function(event) {
        let frm = document.getElementById("frm");
        frm.action = "/board/insertBoard";
        frm.submit();
        alert('글 작성이 완료되었습니다.');
    }
}

function writeEditor() {
    CKEDITOR.replace('contents', {
        filebrowserUploadUrl: '/fileUpload',
        height: '500px'
    });
}
  1. save라는 id를 가진 버튼이 클릭되는 순간 frm 이라는 id를 가진 폼을 /board/insertBoard URL로 전송하고 글 작성이 완료되었다는 알림창을 띄운다.
  2. ckeditor의 contents라는 id를 가진 요소(게시글 내용이 들어가는 필드)에 파일 업로드 기능을 추가하여 사진을 업로드할 수 있도록 하였고, height로 높이 지정을 해주었다.

5. sql-board.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="board.mapper.BoardMapper">
    <insert id="insertBoard" parameterType="board.vo.BoardVo">
        <![CDATA[
            INSERT INTO board
                (
                    title,
                    contents,
                    created_datetime,
                    username,
                    nickname
                )
            VALUES
                (
                   #{title},
                   #{contents},
                   now(),
                   #{username},
                   #{nickname}
                )
            ]]>
    </insert>
</mapper>

 

프로젝트 전체 코드 Github 주소

https://github.com/sungwoo-jo/Staffriends-Project

 

GitHub - sungwoo-jo/Staffriends-Project: AI 스마트 시각장애인 지팡이

AI 스마트 시각장애인 지팡이. Contribute to sungwoo-jo/Staffriends-Project development by creating an account on GitHub.

github.com

 

728x90