부트캠프/TIL

[부트캠프] TIL - N:M 연관관계 구현

purple95 2024. 8. 29. 03:07

User 테이블

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "users")
public class User extends Timestamped{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long user_id;

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String email;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserSchedule> userSchedules = new ArrayList<>();

    public User(UserRequestDTO userRequestDTO) {
        this.username = userRequestDTO.getUsername();
        this.email = userRequestDTO.getEmail();
    }

    //User측에서도 Schedule 등록시 중간다리 객체로 저장.
    public void addSchedule(Schedule schedule){
        UserSchedule userSchedule = new UserSchedule(schedule, this);
        userSchedules.add(userSchedule);
    }
}

 

Schedule 테이블

@Entity
@Getter
@Setter
@ToString(exclude = "comments")     //블로그 문제상황 정리 : 양방향 연관관계에 있는 두 엔티티가 @ToString을 서로 계속 호출하면서 StackOverFlow가 발생.
@NoArgsConstructor
@Table(name = "schedules")
public class Schedule extends Timestamped {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long schedule_id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String contents;

    //외래키 comment_id가 comment엔티티에 있으므로 연관관계의 주인은 Comment, mappedBy는 Comment에 있는 schedule
    @OneToMany(mappedBy = "schedule", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
    private List<Comment> comments = new ArrayList<>();

    //User 고유 식별자 필드를 가짐    하나의 User가 중간다리를 참조하여 여러 Schedule을 가질 수 있음.
    @OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserSchedule> userScheduleList = new ArrayList<>();

    public Schedule(ScheduleRequestDTO scheduleRequestDTO) {
        this.title = scheduleRequestDTO.getTitle();
        this.contents = scheduleRequestDTO.getContents();
    }

    public void addComment(Comment comment) {
        comments.add(comment);
        //Comment를 추가해주면서 comment 자체에 외래키도 설정해줌.
        comment.setSchedule(this);
    }

    // 일정과 관련된 사용자가 입력될 경우, 중간다리 테이블객체로 저장.
    public void addUser(User user){
        UserSchedule userSchedule = new UserSchedule(this,user);
        this.userScheduleList.add(userSchedule);
    }
}

 

 

 

UserSchedule 중간 테이블

@Entity
@Getter
@Setter
@NoArgsConstructor
public class UserSchedule {

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "schedule_id")
    private Schedule schedule;

    public UserSchedule(Schedule schedule, User user) {
        this.schedule = schedule;
        this.user = user;
    }

}

 

 

ERD

 

 

하루를 넘게 소비하여 5단계를 마무리했습니다, 오늘의 TIL은 적기 힘들어서 결과물을 남깁니다.