본문 바로가기
개인 프로젝트/crud-api-project

DB 구조 설계하기

by pon9 2024. 11. 28.

패키지는 일단 이렇게 배치해봤다. github에서 다른 사람들 코드 배치 구조를 많이 참고한거라 왜 이렇게 나누는진 아직은 잘 모르겠다. 아마 가장 직관적이고 각 기능에 따라 잘 나누어져 있어서 그런 듯 하다.

 

그리고 Db 부분을 완성했다.

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
@EntityListeners(AuditingEntityListener.class)
public class BoardDb {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    private String title;

    @NotBlank
    private String content;

    @NotBlank
    @Size(min = 2, max = 10)
    private String nickname;

    @NotBlank
    @Size(min = 4, max = 20)
    private String password;

    @Enumerated(EnumType.STRING)
    @NotNull
    private Category category = Category.FREE;

    @Setter
    @Builder.Default
    @Column(nullable = false, columnDefinition = "int default 0")
    private int like = 0;

    @Setter
    @Builder.Default
    @Column(nullable = false, columnDefinition = "int default 0")
    private int count = 0;

    @OneToMany(mappedBy = "board", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    private List<CommentDb> comments = new ArrayList<>();

    @CreatedDate
    private LocalDateTime createdDate;
}
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EntityListeners(AuditingEntityListener.class)
public class CommentDb {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "boardId", nullable = false)
    @JsonBackReference
    private BoardDb board;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "bigCommentId")
    @JsonBackReference
    private CommentDb bigComment;

    @OneToMany(mappedBy = "bigComment", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    private List<CommentDb> smallComment;

    @NotBlank
    @Size(min = 2, max = 10)
    private String nickname;

    @NotBlank
    @Size(min = 4, max = 20)
    private String password;

    @CreatedDate
    private LocalDateTime createDate;
}

 

일단 회원이 없는 익명 사이트용 api를 만들거라 nickname과 password 칸을 따로 줬다.

기본생성자 생성을 위해 NoArgsConstructor과, 모든 생성자를 위한 AllArgs도 넣었다.

board와 comment 둘 다 builder를 이용해 객체를 쉽게 생성하도록 만들었다.

 

board - bigcomment - smallcomment 가 계층 구조를 가지며, 해당 board가 delete되면 big과 small이 같이 삭제되고, big이 삭제되면 small도 같이 삭제된다. 순환 참조를 막기 위해 부모가 되는 계층에 jsonbackreference, 자식에 jsonmanagedreference어노테이션을 달아줬다.

서비스 계층에서 @Transactional 도 같이 사용해서 일관성 있고 안전하게 만들 생각이다.

 

글 카테고리는 enum으로 관리하고 기본값은 FREE(자유게시판) 으로 설정했다.

 

boardDb의 like와 count는 기본값으로 0을 가지며, 값을 증가시키려면 setter가 필요하지 않을까? 해서 일단은 setter어노테이션을 달아봤다. builder로 빌드될 때 이 두개는 default 값이 필요하니까 이것도 설정해줬다.
그리고 getter는 모든 필드에 적용했다.

 

글과 댓글은 날짜 자동추가를 위해서 CreatedDate와 EntityLisners를 넣었다.

 

확실히 거의 모든 코드가 어노테이션 위주로 돌아간다. 이미 다 자동화가 되어있어서 편리하다.

이제 동작의 핵심이 되는 service를 만들어보자.