JAVA/프로젝트

리팩토링: DTO를 사용한 쿼리 최적화

whyHbr 2024. 9. 3. 15:31
728x90
반응형

 날짜만을 조회하는데 property 안 모든 필드를 조회하고 있어 쿼리문이 과하게 생기는 문제가 발생했다.

이를 줄여보기 위해 repository 에 dto를 사용해봤다.

 

현재 내가 사용하는 것들만 담아 dto를 제작

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PropertyDateDto {

    private Long id;

    private String name;

    private LocalDate endDate;

    private LocalDate startDate;
}

 

 

레포지토리

 

적용전: property 객체 전체를 사용하고 있다. 

 @Query(
            "SELECT p FROM Property p WHERE p.startDate <= :today AND p.endDate >= :today ORDER BY p.id DESC")
    List<Property> findPendingProperties(LocalDate today, Pageable pageable);

 

그래서 여기에 있는 name,areaAddr... 등등이 전부 조회된다.

@Entity
@Getter
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
@Table(name = "property")
public class Property extends BaseEntity {

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String constructor;

    @Column(nullable = false)
    private String areaAddr;

    @Column(nullable = false)
    private String modelHouseAddr;

    @Column(nullable = false)
    private String phoneNumber;

    @Column(nullable = true)
    private String contactChannel;

    @Column(nullable = true)
    private String homePage;

    @Setter
    @Column(nullable = false)
    private int likeCount;

    @Column(nullable = false)
    private LocalDate startDate;

    @Column(nullable = false)
    private LocalDate endDate;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private PropertyType propertyType;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private SalesType salesType;

    @Column(nullable = false)
    private int totalNumber;

    @Column(nullable = false)
    private String companyName;

    @Column(nullable = false)
    private String addrDo;

    @Column(nullable = false)
    private String addrGu;

    @Column(nullable = false)
    private String addrDong;

    @Column(nullable = false)
    private String buildingName;

    @ManyToOne
    @JoinColumn(name = "admin_id", nullable = false)
    @JsonBackReference
    private Admin admin;

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL)
    @JsonManagedReference
    private Set<Likes> likes;

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<File> files = new ArrayList<>();

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Area> areas;

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Keyword> keywords;

 

변경 후 :

@Query(
            "SELECT new subscribers.clearbunyang.domain.property.model.PropertyDateDto(p.id, p.name, p.endDate, p.startDate) "
                    + "FROM Property p WHERE p.startDate <= :today AND p.endDate >= :today ORDER BY p.id DESC")
    List<PropertyDateDto> findPendingPropertiesDateDto(LocalDate today, Pageable pageable);

select new 패키지 경로 클래스 이름 (별칭.필드이름) + 조건문

여기서 주의할 점은 dto클래스 안에 있는 모든 필드를 다 써줘야 한다는 것

 

 

+ 단일 책임의 원칙을 지기키 위해  default 메서드를 사용한다.

 repo에서 생기는 문제는 repo에서 발생할 수 있도록

@Query(
            "SELECT new subscribers.clearbunyang.domain.property.model.PropertyDateDto(p.id, p.name, p.endDate, p.startDate) "
                    + "FROM Property p WHERE p.startDate <= :today AND p.endDate >= :today ORDER BY p.id DESC")
    List<PropertyDateDto> findPendingPropertiesDateDto(LocalDate today, Pageable pageable);

    default List<PropertyDateDto> getPendingPropertiesDto(LocalDate today, Pageable pageable) {
        List<PropertyDateDto> properties = findPendingPropertiesDateDto(today, pageable);
        return properties != null ? properties : Collections.emptyList();
    }

 

 

728x90