게시판 서비스 - ERD, Entity 설계

Sarah·2026년 4월 27일

ERD

Entity 설계

  • 회원 (USERS)
    • user_id : PK 자동생성
    • name : 회원 이름
    • email : 회원 이메일
    • password : 비밀번호
    • joined_date : 가입 날짜
  • 게시글 (BOARDS)
    • board_id : PK 자동생성
    • user_id : FK 회원 아이디
    • title : 게시글 제목
    • board_comment : 게시글 내용
    • created_at : 작성 일자
  • 댓글 (COMMENTS)
    • comment_id : PK 자동생성
    • board_id : FK 게시글 아이디
    • user_id : FK 회원 아이디
    • comment_content : 댓글 내용
    • created_at : 작성 일자

연관관계 매핑

  • 회원 - 게시글 (일대다)
  • 회원 - 댓글 (일대다)
  • 게시글 - 댓글 (일대다)
@Entity
public class User {
    @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
    private List<Board> boards = new ArrayList<>();

    @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
    private List<Comment> comments = new ArrayList<>();
  }
@Entity
public class Board {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @OneToMany(mappedBy = "board", cascade = CascadeType.REMOVE)
    private List<Comment> comments = new ArrayList<>();
 }
@Entity
public class Comment {
	    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "board_id")
    private Board board;
 }
  • FetchType.Lazy
    - N+1 방지를 위해 지연 로딩 설정
    - 연관된 엔티티를 실제로 사용할 때만 조회하여 불필요한 조인 쿼리 방지
  • CascadeType.REMOVE : 데이터가 삭제되면 연쇄 삭제 되도록 설정

연관관계 편의 메서드

Board Entity

    //== 변경 메서드==//
    private void setUser(User user) {
        this.user = user;
        user.getBoards().add(this);
    }

	//== 삭제 메서드==//
    public void remove() {
        if(this.user!=null) {
            this.user.getBoards().remove(this);
        }
    }
  • setUser : 해당 게시글의 작성자가 등록되면 작성자의 게시글 목록에도 해당 게시글을 추가한다.
  • remove : 해당 게시글의 작성자가 존재한다면, 그 작성자의 게시글 목록에서 해당 게시글을 삭제한다.

Comment Entity

    //==작성자 연관 관계 메서드==//
    private void setUser(User user) {
        this.user = user;
        user.getComments().add(this);
    }

	//==게시글 연관 관계 메서드 ==//
    private void setBoard(Board board) {
        this.board = board;
        board.getComments().add(this);
    }

	//==삭제 메서드==//
    public void remove() {
        if(this.user!=null) {
            this.user.getComments().remove(this);
        }
        if(this.board!=null) {
            this.board.getComments().remove(this);
        }
    }
  • setUser : 해당 댓글의 작성자가 등록되면 작성자의 댓글 목록에 해당 댓글을 추가한다.
  • setBoard : 해당 댓글의 게시글이 정해지면 게시글의 댓글 목록에 해당 댓글을 추가한다.
  • remove : 해당 댓글의 작성자가 존재하면, 그 작성자의 댓글 목록에서 해당 댓글을 삭제하고 / 해당 댓글의 게시글이 존재하면, 그 게시글의 댓글 목록에서 해당 댓글을 삭제한다.
  • Set 메서드들은 private 으로 하여 엔티티 내부의 생성 메서드에서만 호출되도록 하였다.

도메인 주도 개발 (DDD)

  • 객체의 일관성을 유지하고 데이터 변경 의도를 명확히 하기 위해 Setter 사용을 지양하고 생성, 변경, 수정 메서드를 만들어서 사용하였다.
  • 생성 메서드들은 외부에서 호출 할 수 있도록 static 으로 하였다.
  • 해당 엔티티를 생성 메서드가 아닌 기본 생성자로 외부에서 생성할 수 없도록 기본 생성자를 protected로 막아서 무분별한 객체 생성을 방지하였다.
    @NoArgsConstructor(access = AccessLevel.PROTECTED)

User Entity

    //==생성 메서드==//
    public static User createUser(String name, String email, String password, LocalDateTime joinedDate, Role role) {
        User user = new User();
        user.name = name;
        user.email = email;
        user.password = password;
        user.joinedDate = joinedDate;
        user.role = role;
        return user;
    }

    //==변경 메서드==//
    public void changeProfile(String name, String email) {
        this.name = name;
        this.email = email;
    }

Board Entity

    //== 수정 메서드==/
    public void updateBoard(String title, String content) {
        this.title = title;
        this.content = content;
    }


    //==생성 메서드==//
    public static Board createBoard(String title, String content, User user, LocalDateTime createdAt) {
        Board board = new Board();
        board.title = title;
        board.content = content;
        board.setUser(user);
        board.createdAt = createdAt;
        return board;
    }

Comment Entity

    //==생성 메서드==//
    public static Comment createComment(String content, User user, Board board, LocalDateTime createAt) {
        Comment comment = new Comment();
        comment.content = content;
        comment.createAt = createAt;

        comment.confirmUser(user);
        comment.confirmBoard(board);

        return comment;
    }

    //==수정 메서드==//
    public void updateComment(String content, LocalDateTime updateAt) {
        this.content = content;
        this.createAt = updateAt;
    }
profile
헤맨 만큼 내 땅

0개의 댓글