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 등).
글쓰기 제한 로직 구현 예시
SELECT role FROM member WHERE memberid = 'user01';
html
<!-- 관리자일 때만 글쓰기 버튼 표시 -->
<button id="write-btn" style="display: <%= "ADMIN".equals(role) ? "block" : "none" %>;">
글쓰기
</button>
여기 자유게시판은 답변 없음.
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');
SELECT *
FROM board
ORDER BY notice DESC, writeday DESC;
MyBatis를 사용하면 SQL 쿼리를 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>
import com.example.domain.Board;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface BoardMapper {
List<Board> findAllOrderByNoticeAndWriteday();
}
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();
}
}
위 JPA 방식과 동일합니다.
조회한 데이터를 화면에 출력하는 코드입니다.
<!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>