테이블설계 - member(회원), board(자유게시판)

·2024년 11월 19일

개인프로젝트

목록 보기
1/11

member 테이블

CREATE TABLE member (
    midx INT AUTO_INCREMENT PRIMARY KEY,            -- 회원 고유 번호 (기본키)
    memberid VARCHAR(50) NOT NULL UNIQUE,           -- 회원 ID (중복 불가)
    memberpw VARCHAR(100) NOT NULL,                 -- 회원 비밀번호 (암호화 저장 추천)
    memberemail VARCHAR(100) NOT NULL UNIQUE,       -- 회원 이메일 (중복 불가)
    membername VARCHAR(50) NOT NULL,                -- 회원 이름
    memberbirth DATE NOT NULL,                      -- 회원 생년월일 (yyyy-mm-dd 형식)
    memberphone VARCHAR(15) NOT NULL UNIQUE,        -- 회원 전화번호 (중복 불가)
    membergender CHAR(1) NOT NULL,                  -- 회원 성별 (M: 남성, F: 여성)
    regdate DATE NOT NULL DEFAULT CURRENT_DATE,    -- 가입 일자 (기본값: 오늘 날짜)
    delyn CHAR(1) DEFAULT 'N',                      -- 삭제 여부 (Y/N)
    memberip VARCHAR(45) NOT NULL                   -- 회원 마지막 접속 IP (IPv4/IPv6 지원)
    memberlevel TINYINT DEFAULT 1, -- 회원 등급 (기본값: 일반 회원)
    role ENUM('USER', 'ADMIN') DEFAULT 'USER', -- 회원 등급 (기본값: 일반 회원)
);

UNIQUE를 추가하면 중복불가?

회원 등급의 기본 정의

  • USER: 일반 사용자

  • ADMIN: 관리자
    필요하다면 등급을 추가 가능 (예: SUPER_ADMIN, MODERATOR 등).
    글쓰기 제한 로직 구현 예시

SQL 조건으로 등급 확인

SELECT role FROM member WHERE memberid = 'user01';

  • UI에서의 접근 제한
    일반 사용자가 글쓰기 버튼을 보지 못하도록 처리
html
<!-- 관리자일 때만 글쓰기 버튼 표시 -->
<button id="write-btn" style="display: <%= "ADMIN".equals(role) ? "block" : "none" %>;">
    글쓰기
</button>

board 테이블 설계 (자유게시판)

여기 자유게시판은 답변 없음.

CREATE TABLE board (
    bidx INT AUTO_INCREMENT PRIMARY KEY,     -- 게시글 ID (Primary Key)
    midx INT NOT NULL,                       -- 작성자 ID (회원 테이블과의 Foreign Key)
    subject VARCHAR(255) NOT NULL,           -- 제목
    contents TEXT NOT NULL,                  -- 내용
    writer VARCHAR(50) NOT NULL,             -- 작성자 이름
    filename VARCHAR(255),                   -- 첨부파일 이름
    recom INT DEFAULT 0,                     -- 추천 수
    viewcnt INT DEFAULT 0,                   -- 조회 수
    delyn CHAR(1) DEFAULT 'N',               -- 삭제 여부 ('Y' 또는 'N')
    writeday DATETIME DEFAULT NOW(),         -- 작성일
    modifyday DATETIME DEFAULT NULL,         -- 수정일
    ip VARCHAR(45) NOT NULL                  -- 작성자 IP 주소 (IPv6 대응)
    notice CHAR(1) DEFAULT 'N'; 			 -- 'Y': 공지사항, 'N': 일반 게시글
);

외래 키 제약(Foreign Key Constraint)은 회원 ID와 게시글 작성의 연관성을 보장하기 위해 추가하는 것입니다. 이를 통해 게시글(board)은 반드시 존재하는 회원(member)에 의해서만 작성되도록 강제할 수 있습니다.

외래 키 제약의 목적

  • 데이터 무결성 보장:
    board 테이블에서 midx(회원 ID)가 member 테이블에 존재하지 않는 값을 가지지 않도록 보장합니다.
    예를 들어, 탈퇴한 회원의 ID를 가진 게시글을 작성할 수 없게 됩니다.

  • 데이터 일관성 유지:
    회원이 삭제될 경우, 해당 회원이 작성한 게시글도 함께 삭제하거나(ON DELETE CASCADE), 회원 ID를 NULL로 설정(ON DELETE SET NULL)하는 등의 처리가 가능합니다.

외래 키 제약 추가

ALTER TABLE board
ADD CONSTRAINT fk_board_member
FOREIGN KEY (midx) REFERENCES member(midx)
ON DELETE CASCADE; -- 회원 삭제 시 관련 게시글도 삭제

공지사항 글 작성

INSERT INTO board (midx, subject, contents, writer, notice)
VALUES (1, '공지사항 제목', '이것은 공지사항입니다.', '관리자', 'Y');
  • 공지사항 글을 작성할 때 notice 값을 'Y'로 설정합니다. 일반 게시글은 기본값인 'N'을 사용합니다.
SELECT * 
FROM board
ORDER BY notice DESC, writeday DESC;
  • 공지사항 상단 고정 쿼리
    SELECT 쿼리에서 ORDER BY 조건을 사용하여 공지사항을 상단에 표시합니다.

2. MyBatis로 구현

MyBatis를 사용하면 SQL 쿼리를 XML 파일에 정의하고, 매퍼 인터페이스를 통해 호출합니다.

(1) 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="com.example.mapper.BoardMapper">
    <select id="findAllOrderByNoticeAndWriteday" resultType="com.example.domain.Board">
        SELECT * 
        FROM board
        ORDER BY notice DESC, writeday DESC
    </select>
</mapper>

(2) 매퍼 인터페이스 작성

import com.example.domain.Board;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface BoardMapper {
    List<Board> findAllOrderByNoticeAndWriteday();
}

(3) Service 클래스 작성

import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class BoardService {
    private final BoardMapper boardMapper;

    public BoardService(BoardMapper boardMapper) {
        this.boardMapper = boardMapper;
    }

    public List<Board> getBoardList() {
        return boardMapper.findAllOrderByNoticeAndWriteday();
    }
}

(4) Controller 작성

위 JPA 방식과 동일합니다.

3. 뷰 파일 작성 (board/list.html)

조회한 데이터를 화면에 출력하는 코드입니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Board List</title>
</head>
<body>
    <h1>게시판</h1>
    <table>
        <thead>
            <tr>
                <th>글 번호</th>
                <th>제목</th>
                <th>작성자</th>
                <th>작성일</th>
                <th>공지 여부</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="board : ${boards}">
                <td th:text="${board.bidx}"></td>
                <td th:text="${board.subject}"></td>
                <td th:text="${board.writer}"></td>
                <td th:text="${board.writeday}"></td>
                <td th:text="${board.notice}"></td>
            </tr>
        </tbody>
    </table>
</body>
</html>

0개의 댓글