이전에 설계한 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();
}
}
'web > 맛슐랭 Project' 카테고리의 다른 글
| 맛슐랭 - 맛집 리뷰 service 구현 (CRUD) (0) | 2024.03.27 |
|---|---|
| 맛슐랭 - 맛집 리뷰 생성을 위한 Repository 구현 (0) | 2024.03.27 |
| 맛슐랭 - 카카오 지도 API 사용하기 (0) | 2024.03.27 |
| 맛슐랭 - db 설계 (0) | 2024.03.27 |
| 맛슐랭 - 스프링부트 OAuth2 로그인 구현 (소셜로그인,간편로그인) (0) | 2024.03.20 |