데이터베이스 변경
PostgreSQL → MySQL으로 변경했다.
PostgreSQL의 대표적인 장점은 다음과 같다.
- 복잡한 쿼리에 탁월
- NoSQL 및 다양한 형식(JSON, hstore, XML 등) 지원
- 다중 버전 동시성 제어
해당 프로젝트에서는 이러한 장점을 하나도 써먹지 못하고 있었다.
복잡한 쿼리가 아닌 JPA로 해결했고, 다른 형식을 저장하지도 않으며, 동시성 제어를 고민할 필요가 없었던 것이다.
단순히 '써보고 싶다'를 넘어 해당 기술을 쓰는 이유가 있어야 한다고 생각해서 바꾸게 되었다.
설치와 관리가 비교적 쉽고, 빠르고, 안정적이며 간단한 데이터베이스인 MySQL으로 변경하게 되었다.
상세정보: MySQL vs PostgresSQL
Entity 수정
1. 필요 없는 어노테이션 제거
//빌더 사용 및 변경사항 메소드 생성으로 제거
@Setter
//빌더 패턴에 필요한 어노테이션 -> 생성자 빌더 패턴으로 변경
@Builder
@AllArgsConstructor
2. 생성자 위에 빌더 선언
기존에는 class 위에 빌더를 선언하여 사용했다. (@AllArgsConstructor, @NoArgsConstructor 필수)
다음과 같은 문제점이 있다.
- 모든 매개변수가 생성자의 파람으로 들어감
- 객체 생성 시 받지 않아야 할 매개변수들도 빌더에 노출
이와 같은 문제점을 해결하기 위해서 생성자위에 @Builder을 선언했다.
@Builder
public Review(User user, Store store, String content, String imgSrc, int grade) {
this.user = user;
this.store = store;
this.content = content;
this.imgSrc = imgSrc;
this.grade = grade;
this.likes = 0;
}
3. 양방향의존 제거
@ManyToOne, @OneToMany 사용으로 순환참조 발생으로 @ManyToOne만 사용
//단방향의존으로 더 이상 필요하지 않음
@JsonIgnoreProperties({"reviewList"})
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
DTO 분할, toDto 로직 생성
기존 코드는 Dto에 대한 개념이 명확히 잡히지 않아 Entity와 같은 클래스를 만들고 거기에 다 때려 넣은 뒤
필요한 값만 빼서 사용하였다.
꼭 필요한 정보만 인자로 가지고 있는 Dto를 만들기 위해 메서드에 따라 분리하였다.
├── dto
│ ├── request
│ │ ├── PostReviewDto.java
│ │ └── PutReviewDto.java
│ └── response
│ └── GetReviewDto.java
@Getter
@NoArgsConstructor
public class PostReviewDto {
@ApiModelProperty(value = "리뷰 내용", example = "맛있었어요")
@NotNull
String content;
@ApiModelProperty(value = "리뷰 이미지 주소", example = "")
String imgSrc;
@ApiModelProperty(value = "리뷰 별점", example = "5")
@Positive @Max(value = 5)
int grade;
}
@Getter
@NoArgsConstructor
public class GetReviewDto {
@ApiModelProperty(notes = "리뷰 고유번호", example = "1", required = true)
private Long id;
@ApiModelProperty(notes = "리뷰 작성자 정보", required = true)
private UserMapDto user;
@ApiModelProperty(notes = "리뷰 고유번호", example = "1", required = true)
private Long storeId;
@ApiModelProperty(notes = "리뷰 내용", example = "맛있었어요", required = true)
private String content;
@ApiModelProperty(notes = "리뷰 사진 주소", example = "")
private String imgUrl;
@ApiModelProperty(notes = "리뷰 생성 시간", example = "2023-04-26T08:02:35.401Z", required = true)
private LocalDateTime createdAt;
@ApiModelProperty(notes = "리뷰 수정 시간", example = "2023-04-26T08:02:35.401Z", required = true)
private LocalDateTime updatedAt;
@ApiModelProperty(notes = "리뷰 등급", example = "5", required = true)
private int grade;
@ApiModelProperty(notes = "리뷰 좋아요 개수", example = "0", required = true)
private int like;
...
}
위와 같이 메소드에 따라 Dto를 나누고 필요한 인자들을 넣어 주었다.
이와 더불어 Get요청 같은 경우 Entity를 Dto로 변환하는 코드가 반복적으로 나타나게 된다.
반복적으로 나타나는 코드를 가독성 있게 한 줄로 표현해 주기 위해 toDto메소드를 생성하였다.
public static GetReviewDto toEntity(Review review) {
return GetReviewDto.builder()
.id(review.getId())
// .user()
.storeId(review.getStore().getId())
.content(review.getContent())
.imgUrl(review.getImgSrc())
.grade(review.getGrade())
.like(review.getLikes())
.createdAt(review.getCreatedAt())
.updatedAt(review.getUpdatedAt())
.build();
}
/**
* 리뷰 조회
*/
@Override
public List<GetReviewDto> getReviews(Long storeId) {
Store store = storeRepository.findById(storeId) .orElseThrow(() -> new IllegalArgumentException("등록되지 않은 가게 입니다"));
List<Review> reviews = reviewRepository.findByStore(store);
List<GetReviewDto> getReviewDtos = new ArrayList<>();
for (Review review : reviews) {
//반복되는 코드
// GetReviewDto getReviewDto = GetReviewDto.builder()
// .id(review.getId())
// .user()
// .storeId(review.getStore().getId())
// .content(review.getContent())
// .imgUrl(review.getImgSrc())
// .grade(review.getGrade())
// .like(review.getLikes())
// .createdAt(review.getCreatedAt())
// .updatedAt(review.getUpdatedAt())
// .build();
GetReviewDto getReviewDto = GetReviewDto.toDto(review);
getReviewDtos.add(getReviewDto);
}
return getReviewDtos;
}
'💻 프로젝트 > 🍝 홍잇' 카테고리의 다른 글
[HongEat] 리팩토링 - Enum/ParameterBinding(Converter) (0) | 2023.10.03 |
---|---|
[HongEat] 리팩토링 - Enum/toJson(@JsonValue) (0) | 2023.04.22 |
[HongEat] 리팩토링 - Enum/toEntity(@JsonCreator, @EnumValid) (0) | 2023.04.22 |
[HongEat] 리팩토링, 어떻게 진행했는가 (0) | 2023.04.22 |