본문 바로가기
web/맛슐랭 Project

맛슐랭 - 엔티티 등록

by su0a 2024. 3. 27.

이전에 설계한 ERD를 토대로 엔티티를 구현했다.

 

1. Member 

  • 네이버나 카카오에서 닉네임을 변경하였을 경우 간편 로그인 시 동일하게 변경이 이루어지도록 하기 위해 update함수를 만들었다.
  • 사용자의 권한을 확인하기 위해 getRoleKey함수도 만들었다.
  • Role을 String 타입으로 db에 저장하기 위해 Enumtype.STRING을 명시했다.
@Entity
@Getter
@NoArgsConstructor
public class Member {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String email;

    private String nickname;

    @Enumerated(EnumType.STRING)
    private Role role;

    @OneToMany(mappedBy = "member",orphanRemoval = true)
    private List<Review> reviews;

    @OneToMany(mappedBy = "member",orphanRemoval = true)
    private List<Wishlist> wishlists;

    @Builder
    public Member(String email, String nickname, Role role){
        this.email=email;
        this.nickname=nickname;
        this.role=role;
        this.reviews=new ArrayList<>();
        this.wishlists=new ArrayList<>();
    }

    public Member update(String nickname){
        this.nickname=nickname;
        return this;
    }

    public String getRoleKey(){
        return this.role.getKey();
    }
}

Member 클래스에서 사용할 목적으로 Role을 만들어주었다. 간편 로그인 로직 내에서 role을 사용할 경우 'ROLE_' 가 앞에 붙어 있어야 하므로 key값에 'ROLE_'를 붙여주었다.

@Getter
@RequiredArgsConstructor
public enum Role {
    //스프링 시큐리티에서는 권한 코드에 항상 ROLE이 앞에 있어야 함
    GUEST("ROLE_GUEST","손님"),
    USER("ROLE_USER","일반사용자");

    private final String key;
    private final String title;
}

 

2. BaseEntity

  • BaseEntity를 상속한 엔티티일 경우 해당 엔티티가 db에 저장 또는 수정될 때 생성시간이 생성된다.
@Getter
@MappedSuperclass //추상클래스에 사용할 수 있으며 엔티티가 될 수 없고 상속을 통해서 사용해야 함
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {

    @CreatedDate //jpa 저장소가 save()할 때 자동으로 생성시간을 만듦
    @Column(updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate //jpa 저장소가 수정할 때 자동으로 생성시간을 만듦
    private LocalDateTime lastModifiedAt;
}

BaseEntity를 사용하기 위해 JpaAuditingConfig클래스를 만들어주었다.

이 클래스는 Spring Data JPA에서 자동으로 생성 및 수정일을 관리하기 위해 사용된다.

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}

 

3. Place

  • 위도 값을 posX, 경도 값을 posY로 저장한다. 
  • 리뷰 등록 시 저장된 음식점 상호명, 주소 등을 받아 entity로 저장하기 위해 toEntity 함수를 만들었다.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
public class Place {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String place_name;
    private String address;
    private String posX; //위도
    private String posY; //경도

    @OneToMany(mappedBy = "place", orphanRemoval = true)
    private List<Review> reviews;

    public static Place toEntity(String place_name,String address,String posX,String posY){
        return Place.builder()
                .place_name(place_name)
                .address(address)
                .posX(posX)
                .posY(posY)
                .reviews(new ArrayList<>())
                .build();
    }
}

 

4. Review

  • 가장 연관관계가 많이 매핑되어 있는 엔티티이다.
  • Member, Place는 다대일 조인이므로 지연로딩을 명시해주어야 한다.
  • 리뷰 수정 시 먹은 음식, 제목, 내용만 수정할 수 있도록 할 계획이라 modify 함수를 아래와 같이 만들었다.
  • 또한 리뷰 수정 시 이미지를 업로드 하면 원래 이미지는 삭제 되도록 하기 위해 uploadImageListClear 함수를 만들어 주었다.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
public class Review extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="place_id")
    private Place place;

    private List<String> eatFoods;

    private String title;
    private String content;

    @OneToMany(mappedBy = "review")
    private List<UploadImage> uploadImages;

    public static Review toEntity(ReviewCreateRequest reviewCreateRequest,Place place, Member member){
        return Review.builder()
                .member(member)
                .place(place)
                .eatFoods(reviewCreateRequest.getEatFoods())
                .title(reviewCreateRequest.getTitle())
                .content(reviewCreateRequest.getContent())
                .uploadImages(new ArrayList<UploadImage>())
                .build();

    }

    public Review modify(List<String> eatFoods,String title,String content){
        if(eatFoods.size()>0){
            this.eatFoods=eatFoods;
        }
        if(!title.isEmpty()){
            this.title=title;
        }
        this.content=content;
        return this;
    }

    public void uploadImageListClear() {
        this.uploadImages=new ArrayList<>();
    }
}

 

5. UploadImage

  • 이미지 업로드 시 엔티티로 저장하기 위해 만들었다.
  • 저장된 이미지들은 resource/static/upload-images 내에 있지만 추후에 aws를 사용하여 클라우드에 저장할 예정이다.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
public class UploadImage {

    @Id
    @GeneratedValue
    private Long id;

    private String originalFilename; //원본 파일명
    private String savedFilename; //서버에 저장된 파일명

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "review_id")
    private Review review;

}

 

6. Like

  • 찜한 목록을 저장하기 위한 엔티티이다.
  • 다대일 관계이므로 지연로딩을 명시해주자.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Table(name = "`LIKE`")
public class Like {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Place place;

    @ManyToOne(fetch = FetchType.LAZY)
    private Member member;

    public static Like createLike(Place place, Member member){
        return Like.builder()
                .place(place)
                .member(member)
                .build();
    }
}