목차
본격적으로 프로젝트 주제에 맞는 코드 구성을 해보고자 한다.
먼저, 가장 처음 이야기 했던 주제를 다시 되짚어보자
- 사용자끼리 일정공유 (일정을 공유 승인 방식은 메시지를 이용했다)
- 그룹 캘린더 구성
- 알림 기능
처음 구성할때 연관관계 매핑이 살짝 헷갈렸다. 초기에 다대일로 구성했다가 생각해보니 다대다 관계였고, 다대다 관계를 many to many를 사용하여 구성하였다가, 이 방법보다 중간테이블을 사용하여야 한다는 사실을 깨닫고 재수정 하는 과정도 있었다.
many to many를 사용하면 안좋다는 건 알고있었지만 정확하게 무슨 이유인지는 잘 알지 못해 구글링을 한 결과 한 블로그에서 친절하게 적어주었다.
- 편리해 보이지만 실무에서 사용하면 안된다.
- 개발하다 보면, 연결 테이블이 단순히 연결만 하고 끝나지 않는다. 조인 테이블 자체에 주문시간, 수량 같은 추가 데이터가 많이 들어갈 수 있다.
- 하지만, 매핑 정보만 넣는 것이 가능하고, 추가 정보를 넣는 것 자체가 불가능하다.
- 그리고 중간 테이블이 숨겨져 있기 때문에 예상하지 못하는 쿼리들이 나간다.
- 이런 문제점들 때문에 실무에서는 안쓰는게 맞다고 본다.
참고 블로그 https://ict-nroo.tistory.com/127
이곳에 모든 코드를 올리기는 제한이 있기 때문에 핵심적인 코드만 적어보고자 한다. (추가 코드는 깃허브에 제공되어있습니다.)
Member.java
- MyGroup 테이블과 ManyToMany관계로 이어져 있지만, 중간 테이블을 만들어 줘서 연결테이블과 OneToMany관계로 구성해주었다.
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String nickname;
@Column(nullable = false)
private String phoneNumber;
@Enumerated(EnumType.STRING)
private Authority authority;
@OneToMany(mappedBy = "member")
private List<MemberGroup> memberGroups = new ArrayList<>();
// Schedule 엔티티와 다대다 관계를 가짐
@OneToMany(mappedBy = "member")
private List<Schedule> schedules = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Todo> Todos = new ArrayList<>();
@OneToMany(mappedBy = "owner")
private List<MyGroup> ownedGroups = new ArrayList<>();
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setPassword(String password) {
this.password = password;
}
@Builder
public Member(Long id, String email, String password, String nickname, Authority authority,String phoneNumber) {
this.id = id;
this.email = email;
this.password = password;
this.nickname = nickname;
this.authority = authority;
this.phoneNumber = phoneNumber;
}
}
MyGroup.java
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String nickname;
@Column(nullable = false)
private String phoneNumber;
@Enumerated(EnumType.STRING)
private Authority authority;
@OneToMany(mappedBy = "member")
private List<MemberGroup> memberGroups = new ArrayList<>();
// Schedule 엔티티와 다대다 관계를 가짐
@OneToMany(mappedBy = "member")
private List<Schedule> schedules = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Todo> Todos = new ArrayList<>();
@OneToMany(mappedBy = "owner")
private List<MyGroup> ownedGroups = new ArrayList<>();
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setPassword(String password) {
this.password = password;
}
@Builder
public Member(Long id, String email, String password, String nickname, Authority authority,String phoneNumber) {
this.id = id;
this.email = email;
this.password = password;
this.nickname = nickname;
this.authority = authority;
this.phoneNumber = phoneNumber;
}
}
Schedule.java
-개인의 스케줄
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "schedules")
public class Schedule {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column
private String content;
@Column(nullable = false)
private LocalDateTime startDateTime;
@Column(nullable = false)
private LocalDateTime endDateTime;
@Column(nullable = false)
private boolean alarm;
private LocalDateTime alarmDateTime;
@OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Image> images = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
}
GroupSchedule.java
-그룹의 스케줄
@Entity
@Getter
@Setter
@NoArgsConstructor
public class GroupSchedule {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column(nullable = false)
private LocalDateTime startDateTime;
@Column(nullable = false)
private LocalDateTime endDateTime;
@Column(nullable = false)
private boolean alarm;
private LocalDateTime alarmDateTime;
@OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Image> images = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id")
private MyGroup myGroup;
@Builder
public GroupSchedule(Long id, String title, String content, LocalDateTime startDateTime, LocalDateTime endDateTime, boolean alarm, LocalDateTime alarmDateTime, List<Image> images, MyGroup myGroup) {
this.id = id;
this.title = title;
this.content = content;
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
this.alarm = alarm;
this.alarmDateTime = alarmDateTime;
this.images = images;
this.myGroup = myGroup;
}
}
SharedSchedule.java
- SharedSchedule 테이블을 추가로 구성한 이유는 A사용자가 B사용자에게 일정을 공유하고싶을때, SharedSchedule테이블에 그 일정을 추가하고, B사용자는 SharedSchedule 테이블에 자신에게 공유된 테이블이 있을 경우 그 일정도 자신의 개인일정에 추가가 되도록 구성하고자 SharedSchedule 테이블을 구성하였다. 여기서, 그냥 무작정 공유하면 추가되는 것이 아닌 boolean 형식의 approbed 변수를 추가하여 B사용자가 허용했을 경우 즉 true일 경우에만 추가하도록 구성했다.
@Entity
@Table(name = "shared_schedules")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SharedSchedule {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "schedule_id")
private Schedule schedule;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
private boolean approved = false;
}
Message.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column(nullable = false)
private boolean deletedBySender;
@Column(nullable = false)
private boolean deletedByReceiver;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "shared_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private SharedSchedule sharedSchedule;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "sender_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private Member sender;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "receiver_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private Member receiver;
public void deleteBySender() {
this.deletedBySender = true;
}
public void deleteByReceiver() {
this.deletedByReceiver = true;
}
public boolean isDeleted() {
return isDeletedBySender() && isDeletedByReceiver();
}
}
GroupMessage.java
package com.example.Capstone.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class GroupMessage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String message;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id")
private MyGroup group;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id")
private Member owner;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "sender_id")
private Member sender;
public GroupMessage(String message, MyGroup group, Member owner, Member sender) {
this.message = message;
this.group = group;
this.owner = owner;
this.sender = sender;
}
}
- 추가적으로 아직 작성하지 않은 Todo나 Image도 있지만 기본적인 틀을 구성한 뒤에 다루고자 한다.
'프로젝트 > 공유 캘린더' 카테고리의 다른 글
공유 캘린더 만들기 #5 (API 문서화 및 UI 구성) (0) | 2023.08.03 |
---|---|
공유 캘린더 만들기 #4 (Service 및 스케줄러 디테일 구성) (0) | 2023.07.17 |
공유 캘린더 만들기 #2 (JWT를 이용한 회원가입 로그인) (0) | 2023.07.15 |
공유 캘린더 만들기 #1 (Spring boot + Docker + AWS) (0) | 2023.07.06 |