Blog

[Spring][iLanD] MVP - 주요 엔티티 생성 및 연관관계 구성

Category
Author
Tags
PinOnMain
1 more property
게시판 - 게시글(4종) - 파일
모든 콘텐츠는 사실 게시글이라 볼 수 있다. 그 컬럼의 내용이 달라지거나 위치만 달라질 뿐, 파일이 있는것 없는것 추후에 추가가 필요할것을 고려하여 파일 테이블을 별도로 분리하고 연관관계로 처리했다.
Board.java
게시판의 틀이되는 게시판 엔티티이다. 각 게시글들의 종류를 @OneToMany 연관관계를 통해서 각 리스트들을 가져오도록 설정했다.
package com.yzpocket.iland.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Entity @Builder @AllArgsConstructor @NoArgsConstructor @Getter @Table(name = "boards") public class Board extends TimeStamped{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String title; @Column @Enumerated(value = EnumType.STRING) private BoardTypeEnum type; @ManyToOne @JoinColumn(name = "user_id") private User user; @OneToMany(mappedBy = "board") List<Notice> noticeList = new ArrayList<>(); @OneToMany(mappedBy = "board") List<Video> videoList = new ArrayList<>(); @OneToMany(mappedBy = "board") List<Info> infoList = new ArrayList<>(); @OneToMany(mappedBy = "board") List<Info> gameList = new ArrayList<>(); }
Java
복사
Notice.java
첫번째 게시글의 엔티티인 공지 게시글이다. 게시판:공지게시글 은 1:N 연관관계를 가지고 있다. 이것과 동일하게 Info, Video, Game 게시글이 동일한 컬럼, 연관관계를 가지고 있다고 생각하면 된다. 대표적으로 Notice부분의 코드는 다음과 같다.
package com.yzpocket.iland.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Entity @Builder @AllArgsConstructor @NoArgsConstructor @Getter @Table(name = "notices") public class Notice extends TimeStamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long noticeId; @Column private String noticeTitle; @Column private String noticeWriter; @Column private String noticeContents; @Column @Enumerated(value = EnumType.STRING) private NoticeTypeEnum noticeType; @ManyToOne @JoinColumn(name = "board_id") private Board board; @OneToMany(mappedBy = "notice") List<File> fileList = new ArrayList<>(); }
Java
복사
File.java
Notice, Info, Video, Game 게시글 모두 파일이 첨부될 수 있다. 현재 Game부분은 어떻게 구성할지 좀 더 사례를 찾아봐야하지만, 기본적으로 무언가 여러 종류 게임을 올린다는 의미에서는 게시글과 동일한 것으로 생각했으며 일단 더미로 작성해두었다.
File은 Multipart로 업로드하는 식으로 서버내 특정 공간에 저장되도록 할 것이며, 이미지나 영상은 해당 경로에서부터 추출하여 실행 또는 로드하는 방식을 사용하게 될 것으로 판단된다.
여러 파일들이 첨부될 수 있는 상황을 고려하여 1:N 연관관계를 맵핑했다.
package com.yzpocket.iland.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Builder @AllArgsConstructor @NoArgsConstructor @Getter @Table(name = "files") public class File { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long Id; @Column private String fileName; @Column private Long fileSize; @Column @Enumerated(value = EnumType.STRING) private FileTypeEnum fileType; @ManyToOne @JoinColumn(name = "Notice_id") private Notice notice; @ManyToOne @JoinColumn(name = "Info_id") private Info info; @ManyToOne @JoinColumn(name = "Video_id") private Video video; @ManyToOne @JoinColumn(name = "Game_id") private Game game; }
Java
복사
JPA에 의해 자동으로 테이블이 생성된다.
이제 공지 게시판 CRUD를 구현하면 사실 다른 부분들은 복사 붙여넣기와 다를바 없다. 파일 업로드와 로드 부분을 잘 체크해야 한다.
orphanremoval = true
부모 자식 관계에서 부모 요소가 삭제되면 관련된 고아가된 자식 요소를 삭제할지 여부는 생각해봐야겠다.
우선 관리자 유저는 게시판 4종을 생성할텐데, 관리자 유저를 삭제하면 모든 게시판이 사라질 수 있다. 이에 연계되어 모든 게시글, 모든 파일이 삭제 될 수 있기 때문에 연관관계에 따른 삭제 부분은 신중히 생각해야 한다. 우선 위 상황은 고려하지 않고 있다.
하지만 어떤 공지사항이 삭제 될 때, 관련된 첨부파일은 삭제되어도 된다. 그 파일이 남아있을 필요가있는가? 없다.
이런 방식으로 논리적으로 말이 되는지 하나씩 확인하여 orphanremoval 옵션을 사용해야겠다. 이 부분은 API를 구현하면서 천천히 생각해보자.