0

[Spring MVC] 게시판 MySQL, DTO, mapper #4

Last Updated: 2022년 12월 14일

게시판을 만들기 위한 DB, DTO, mapper 등을 만듭니다.

출처: 내 컴퓨터

MySQL

  • 첨부파일, 게시판 카테고리 등등이 들어가 있는데 필요한 부분만 입력하시면 됩니다.
CREATE TABLE `tbl_board` (
	`seq` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(20) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`email` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`homepage` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`title` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`content` VARCHAR(4000) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`password` VARCHAR(20) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`count` INT(11) NULL DEFAULT '0',
	`ip` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`regdate` DATE NULL DEFAULT NULL,
	`check_yn` VARCHAR(2) NULL DEFAULT 'N' COMMENT '승인여부' COLLATE 'utf8_general_ci',
	`pos` INT(11) NULL DEFAULT NULL,
	`depth` INT(11) NULL DEFAULT NULL,
	`view_cnt` INT(11) UNSIGNED NULL DEFAULT NULL,
	`cate_cd` VARCHAR(20) NULL DEFAULT NULL COMMENT '게시판 카테고리' COLLATE 'utf8_general_ci',
	`original_file_name` VARCHAR(260) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`stored_file_name` VARCHAR(36) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`file_size` INT(11) NULL DEFAULT NULL,
	`original_file_name2` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`stored_file_name2` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`file_size2` INT(11) NULL DEFAULT NULL,
	`file_cnt` INT(11) NULL DEFAULT '0',
	PRIMARY KEY (`seq`) USING BTREE
)

boardDTO.java (VO)

  • /프로젝트명/src/main/java/kr/co/narrator/board/dto/BoardDTO.java
  • DTO 와 VO 를 혼용해서 사용하기도 하고, 엄격하게 구분해서 사용하기도 하는데 어떻게 구분이 되는지 확인하고, 필요 또는 합의에 따라 사용하면 된다.
  • DTO (Data Transfer Object)는 계층간의 데이터를 전송하기 위한 객체로써, getter/setter를 사용하여 보내는 사람은 setter를 사용하여 값을 담고, 받는 사람은 getter를 사용하여 값을 꺼내 쓴다. 이때 값의 변조를 막고 싶다면 생성자로 불변 객체로 만들어 버리면 된다. 또한 DTO의 특성상 데이터 전달만은 목적으로 사용하기 때문에 getter/setter를 제외한 다른 로직이 필요가 없다.
  • VO (Value Object)의 경우 값 그 자체를 나타내는 객체로써, 핵심은 필드 값이 같다면 두 객체를 같은 객체로 본다는 것이다. 이때 당연하게도 주소값을 비교하는 경우의 문제점을 위해서 hashcode()와 equals()를 오버라이딩(재정의)하여 필드 값이 같다면 같은 객체로 인식될 수 있도록 해주어야 한다.
DTOVO
목적계층간 데이터 전달
(레이어와 레이어 사이에서 사용 가능)
값 자체 표현
(모든 레이어에서 사용 가능)
동등성필드값이 같아도 다른 객체로 식별
필드값이 같으면 같은 객체로 식별
가변성setter 존재 시 값이 변할 수 있음(가변)
setter 비존재 시 불가변
값이 변하지 않음(불변)
로직getter/setter 외의 로직이 필요없음getter/setter 외의 로직이 있어도 상관없음
@Override
public int hashCode() {
package kr.co.narrator.board.dto;

import java.util.Date;

/*
 * 게시판 DTO(VO)
 * DTO (Data Transfer Object) - 데이터 전달 용도로만 사용되기 때문에 getter/setter 로직만 필요하다.
 * getter, setter 추가
 * 마우스 우클릭 > source > generate getters and setters
 * Alt + Shift + s > generate getters and setters
 */
// 생성자를 이용한 불변 객체
public class BoardDTO {
	
	private int seq;					// 번호
	private String name;				// 작성자
	 private String email;				// 이메일
	 private String homepage;		// 홈페이지
	 private String title;				// 제목
	 private String content;			// 내용
	 private String password;		// 비밀번호
	 private int count;					// 조회수
	 private String ip;					// 등록IP
	 private Date regdate;			// 등록일
	 private String check_yn;		// 체크여부

	public int getSeq() {
		return seq;
	}
	public void setSeq(int seq) {
		this.seq = seq;
	}
        ...

boardMapper.xml

  • /프로젝트명/src/main/resources/mappers/boardMapper.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="kr.co.narrator.board.boardMapper">

	<!-- 검색 공통 -->
	<!-- MyBatis 동적 sql -->
	<sql id="search">
		<choose>
			<when test="searchType == 'all'">
				AND (name LIKE CONCAT('%', #{keyword}, '%')
				OR content LIKE CONCAT('%', #{keyword}, '%')
				OR title LIKE CONCAT('%', #{keyword}, '%'))
			</when>
			<when test="searchType == 'writer'">
				AND name LIKE CONCAT('%', #{keyword}, '%')
			</when>
			<when test="searchType == 'content'">
				AND content LIKE CONCAT('%', #{keyword}, '%')
			</when>
			<when test="searchType == 'title'">
				AND title LIKE CONCAT('%', #{keyword}, '%')
			</when>
		</choose>
	</sql>

	<!-- 게시판 리스트 및 총 갯수 -->
	<select id="boardList" resultType="kr.co.narrator.board.dto.BoardDTO" parameterType="kr.co.narrator.board.common.SearchCriteria">
		SELECT seq, name, title, content, count, regdate, check_yn
		FROM tbl_board
		WHERE 1=1
		<include refid="search" />
		ORDER BY seq DESC
		LIMIT #{pageStart}, #{perPageNum}
	</select>

	<select id="boardListCnt" resultType="int" parameterType="kr.co.narrator.board.common.SearchCriteria">
		SELECT
			count(*)
		FROM
			TBL_BOARD
		WHERE 1=1
		<include refid="search" />
		AND seq > 0
	</select>

	<!-- 게시판 조회 -->
	<select id="boardContent" parameterType="int" resultType="kr.co.narrator.board.dto.BoardDTO">
		SELECT seq, name, title, content, regdate, check_yn
		FROM TBL_BOARD 
		WHERE seq = #{seq}
	</select>

	<!-- 조회수 증가 -->
	<update id="boardContentCount" parameterType="int">
		UPDATE TBL_BOARD SET
		count = count+1
		WHERE seq = #{seq}
	</update>

	<!-- 첨부파일 번호 저장을 위하여 useGen... keyPro... 추가 -->
	<insert id="boardInsert" parameterType="kr.co.narrator.board.dto.BoardDTO" useGeneratedKeys="true" keyProperty="seq">
		INSERT INTO TBL_BOARD (seq, name, title, content, regdate)
		VALUES (
			#{seq}
			, #{name}
			, #{title}
			, #{content}
			, now()
		)
	</insert>

</mapper>