목차

    본격적으로 프로젝트 주제에 맞는 코드 구성을 해보고자 한다.

     

    먼저, 가장 처음 이야기 했던 주제를 다시 되짚어보자

    - 사용자끼리 일정공유 (일정을 공유 승인 방식은 메시지를 이용했다)

    - 그룹 캘린더 구성

    - 알림 기능

     

    처음 구성할때 연관관계 매핑이 살짝 헷갈렸다. 초기에 다대일로 구성했다가 생각해보니 다대다 관계였고, 다대다 관계를 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도 있지만 기본적인 틀을 구성한 뒤에 다루고자 한다.