댓글에 특정 단어가 있는 게시물을 검색하는 쿼리이다.
FROM Board A
WHERE EXISTS (SELECT 1 FROM Comment WHERE no = A.no AND content LIKE '%내용%');
queryFactory
.selectFrom(member)
.where(member.team.id.gt(member.team.leader.id))
.fetch();
@Transactional(readOnly = true)
public List<AdBond> createAdBond(LocalDate startDate, LocalDate endDate, List<String> orderTypes) {
return queryFactory
.select(Projections.fields(AdBond.class,
adItem.amount.sum().as("amount"),
adItem.txDate,
adItem.orderType,
adItem.customer) // AdBond의 customer 를 바로 지정
)
.from(adItem)
.where(adItem.orderType.in(orderTypes)
.and(adItem.txDate.between(startDate, endDate)))
.groupBy(adItem.orderType, adItem.txDate, adItem.customer)
.fetch();
}
1. entity -> dto로 변경
2. customer객체 대신 customer.id 로 변경
근데 문제가 하나 더있다. 이렇게 dto를 만들고 나서 이 dto에 대한 entity를 다시 저장해주어야한다!
가장 쉬운방법은 다음과 같이 매번 조회하는거겠지만..
@Transactional
public void createAdBond2 (LocalDate startDate, LocalDate endDate, List<String> orderTypes) {
List<AdBondDto> adBondDtos = queryRepository.createAdBondDto(startDate, endDate, orderTypes);
List<AdBond> adBonds = new ArrayList<>();
for (AdBondDto dto : adBondDtos) {
Customer customer = customerRepository.findById(dto.getCustomerId()).get(); // customerId로 Customer Entity 조회 후,
adBonds.add(AdBond.builder()
.amount(dto.getAmount())
.txDate(dto.getTxDate())
.orderType(dto.getOrderType())
.customer(customer) // AdBond Entity와 관계를 맺음
.build());
}
adBondRepository.saveAll(adBonds);
}
이러면 쿼리성능향상을 위해 쿼리가 더 나가게된다
그럼 어떻게 하면 좋을까?
결국 AdBond의 테이블 에는 Customer의 Id만 들어가게 되는데요. 신규 등록하는 AdBond 에서는 ID만 가진 Customer Entity와 관계만 맺기만 하면 그 목적을 달성할 수 있습니다.
@Transactional
public void createAdBond3 (LocalDate startDate, LocalDate endDate, List<String> orderTypes) {
List<AdBondDto> adBondDtos = queryRepository.createAdBondDto(startDate, endDate, orderTypes);
List<AdBond> adBonds = adBondDtos.stream()
.map(adBondDto -> AdBond.builder()
.amount(adBondDto.getAmount())
.txDate(adBondDto.getTxDate())
.orderType(adBondDto.getOrderType())
.customer(new Customer(adBondDto.getCustomerId())) // customerId만 가진 Customer Entity를 사용
.build())
.collect(Collectors.toList());
adBondRepository.saveAll(adBonds);
}
@Getter
@NoArgsConstructor
public class AdBondDto {
...
public AdBond toEntity() {
return AdBond.builder()
.amount(amount)
.txDate(txDate)
.orderType(orderType)
.customer(new Customer(customerId))
.build();
}
}
@Transactional
public void createAdBond4 (LocalDate startDate, LocalDate endDate, List<String> orderTypes) {
List<AdBondDto> adBondDtos = queryRepository.createAdBondDto(startDate, endDate, orderTypes);
List<AdBond> adBonds = adBondDtos.stream()
.map(AdBondDto::toEntity) // dto.toEntity로 한번에 해결
.collect(Collectors.toList());
adBondRepository.saveAll(adBonds);
}
출처
https://github.com/Youngerjesus/Querydsl/blob/master/docs/woowahwan.md
https://jojoldu.tistory.com/518