Java와 spring boot 게시판 프로젝트 - 테이블 설계

최고요·2023년 5월 9일
0

SpringBoot-Board-Project

목록 보기
2/3
post-thumbnail

테이블 설계


  1. 테이블 간 시간과 관련된 컬럼을 상속해 줄 BaseTime테이블
package com.dandelion.dandelion.entity;

import lombok.Getter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass // 모든 JPA 엔티티들이 BaseTimeEntity를 상속 받을 경우 필드도 컬럼으로 인식하도록 한다.
@EntityListeners(AuditingEntityListener.class) // BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다.
public class BaseTimeEntity {

    @CreationTimestamp // 3
    @Column(updatable = false)
    private LocalDateTime localDateTime;

    @UpdateTimestamp // 4
    @Column(insertable = false)
    private LocalDateTime modifiedDate;
}

회원테이블에는 회원가입 날짜와 회원정보 수정 일자가 필요했고, 게시글도 마찬가지였다.
그래서 이를 상속해줄 수 있는 클래스를 작성하여 시간 클래스를 상속받는 테이블들은 컬럼을 가지도록 코드를 작성했다.



  1. 회원정보를 담고있는 member테이블
package com.dandelion.dandelion.entity;

import com.dandelion.dandelion.dto.MemberDTO;
import lombok.*;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
@NoArgsConstructor // 기본 생성자가 생성
@AllArgsConstructor
@Table(name = "membertable") // db에 생성될 테이블 이름
public class MemberEntity extends BaseTimeEntity{ // BaseEntity를 상속
    @Id // pk
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 시퀀스의 역할 auto_increment
    @Column(name="id" , nullable = false)
    private Long id; // 회원번호아이디
    @Column(name ="email",nullable = false , unique = true ,length = 50)
    private String email; // 회원이메일
    @Column(name ="password",nullable = false,length = 100)
    private String password; // 회원비밀번호
    @Column(name ="name",nullable = false,length = 50)
    private String name; // 회원이름
    @Column(name ="role",nullable = false)
    private String role = "user"; // 역할 디폴트 user

    @OneToMany(mappedBy = "member" , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<BoardEntity> boards = new ArrayList<>();
    @OneToMany(mappedBy = "member" , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CommentsEntity> comments = new ArrayList<>();

    public static MemberEntity toMemberEntity(MemberDTO memberDTO){
        MemberEntity memberEntity = new MemberEntity();
        /*DTO에 감긴 값을 Entity로 세팅하는 과정*/
        memberEntity.setId(memberDTO.getId());
        memberEntity.setName(memberDTO.getName());
        memberEntity.setEmail(memberDTO.getEmail());
        memberEntity.setPassword(memberDTO.getPassword());
        memberEntity.setRole(memberDTO.getRole() == null ? "user" : memberDTO.getRole());
        return memberEntity;
    }
}

회원과 게시글의 관계를 설명하자면, 한 명의 회원은 여러 개의 게시글을 작성할 수도 있다
댓글도 마찬가지로, 한 명의 회원은 여러 개의 댓글을 작성할 수 있다

따라서 @OneToMany로 테이블 간의 관계를 설정해주었다.




2. 게시글의 정보를 가지고있는 Board테이블

package com.dandelion.dandelion.entity;

import com.dandelion.dandelion.dto.BoardDTO;
import com.dandelion.dandelion.repository.MemberRepository;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
@NoArgsConstructor // 기본 생성자가 생성
@AllArgsConstructor
@Table(name = "baordtable") // db에 생성될 테이블 이름
public class BoardEntity extends BaseTimeEntity{
    @Id // pk
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 시퀀스의 역할 auto_increment
    @Column(name="id" , nullable = false)
    private Long id; // 게시글 넘버
    @Column(name="title" , nullable = false,length = 100)
    private String title; // 제목
    @Column(name="content" , nullable = false)
    private String content; // 내용
    @Column(name="categories" , nullable = false)
    private String categories; // 카테고리

    @ManyToOne
    @JoinColumn(name = "member_id")
    private MemberEntity member;
    @OneToMany(mappedBy = "board" , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CommentsEntity> comments = new ArrayList<>();


    public static BoardEntity toBoardEntity(BoardDTO boardDTO, MemberEntity member) {
        BoardEntity boardEntity = new BoardEntity();
        boardEntity.setId(boardDTO.getId());
        boardEntity.setCategories(boardDTO.getCategories());
        boardEntity.setTitle(boardDTO.getTitle());
        boardEntity.setContent(boardDTO.getContent());
        boardEntity.setMember(member);
        return boardEntity;
    }

    public String getMemberName() {
        return member != null ? member.getName() : "";
    }

}

게시글은 한 명의 회원의 정보만을 가질 수 있으며, 반대로 댓글은 여러개가 하나의 게시글에 연결되기 때문에
게시글과 회원테이블간의 관계는 @ManyToOne로
게시글과 댓글의 관계는 @OneToMany 로 작성했다.



  1. 댓글의 정보를 가지고있는 comment 테이블
package com.dandelion.dandelion.entity;

import com.dandelion.dandelion.dto.CommentsDTO;
import com.dandelion.dandelion.repository.BoardRepository;
import com.dandelion.dandelion.repository.MemberRepository;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.Optional;

@Entity
@Getter
@Setter
@NoArgsConstructor // 기본 생성자가 생성
@AllArgsConstructor
@Table(name = "conmmentstable") // db에 생성될 테이블 이름
public class CommentsEntity extends BaseTimeEntity{
        @Id // pk
        @GeneratedValue(strategy = GenerationType.IDENTITY) // 시퀀스의 역할 auto_increment
        @Column(name="id" , nullable = false)
        private Long id; // 댓글 고유번호
        @Column(name="title" , nullable = false,length = 100)
        private String content; // 내용

        @ManyToOne
        @JoinColumn(name = "member_id")
        private MemberEntity member;
        @ManyToOne
        @JoinColumn(name = "board_id")
        private BoardEntity board;

        public static CommentsEntity toCommentsEntity(CommentsDTO commentsDTO, MemberRepository memberRepository, BoardRepository boardRepository) {
                CommentsEntity commentsEntity = new CommentsEntity();
                commentsEntity.setId(commentsDTO.getId());
                commentsEntity.setContent(commentsDTO.getContent());

                if (commentsDTO.getMemberId() != null) {
                        Optional<MemberEntity> memberOpt = memberRepository.findById(commentsDTO.getMemberId());
                        memberOpt.ifPresent(commentsEntity::setMember);
                }

                if (commentsDTO.getBoardId() != null) {
                        Optional<BoardEntity> boardOpt = boardRepository.findById(commentsDTO.getBoardId());
                        boardOpt.ifPresent(commentsEntity::setBoard);
                }

                return commentsEntity;
        }

}

댓글은 한명의 회원 그리고 하나의 게시글에만 작성되기때문에
둘다 @ManyToOne 으로 테이블관계를 설정해주면 된다.


profile
i'm best

0개의 댓글