[플러스 주차 개인 과제 중 5번]
- 동적 쿼리에 대한 이해
처음에는 QueryDsl을 활용한 user아이디를 파라미터로 갖는 메서드와 item아이디를 갖는 메서드를 만들고
private final JPAQueryFactory jpaQueryFactory;
@Override
public List<Reservation> getReservationByUserId(Long id){
QReservation reservation = QReservation.reservation;
return jpaQueryFactory.select(reservation)
.from(reservation)
.where(reservation.user.id.eq(id))
.fetch();
}
@Override
public List<Reservation> getReservationByItemId(Long id) {
QReservation reservation=QReservation.reservation;
return jpaQueryFactory.select(reservation)
.from(reservation)
.where(reservation.item.id.eq(id))
.fetch();
}
itemid만 입력을 받지 않으면 getReservationByUserId(userId)를 호출하고 userId만 입력을 받지 않으면 getReservationByItemId(itemId)를 호출하고 둘다 입력받지 않으면 전에 n+1문제를 해결한 과 비슷한 메소드findAllWithItemIdAndUserId()를 호출해 리턴하는 것으로 해결하였다
/**
ReservationService.java
*/
if(itemId==null) {
return reservationRepository.getReservationByUserId(userId);
}else if(userId ==null) {
return reservationRepository.getReservationByItemId(itemId);
}
return reservationRepository.findAllWithItemIdAndUserId();*/
하지만 내가 이해한 바로는 이 기능은 레포지토리가 해야될 것같다는 피드백을 주신것 같다. 그래서 QueryDsl을 활용한 동적 쿼리를 짜기로 했다.
@Override
public List<Reservation> getReservationByUserIdOrItemId(Long userId, Long itemId) {
QReservation reservation=QReservation.reservation;
return jpaQueryFactory.select(reservation)
.from(reservation)
.where(isUserEq(userId),isItemrEq(itemId))
.fetch();
}
private BooleanExpression isUserEq(Long userId) {
QReservation reservation=QReservation.reservation;
return userId!=null ?reservation.user.id.eq(userId):null;
}
private BooleanExpression isItemrEq(Long itemId) {
QReservation reservation=QReservation.reservation;
return itemId!=null ?reservation.user.id.eq(itemId):null;
}
입력받은 id가 없다면 null을 리턴해주는 메소드들을 활용하여 동적쿼리를 짜보았는데 두가지 문제가 발생하는것을 알았다.1. n+1문제,2번째는 내가 원하는대로 userId,itemId각각 주던 안주던 값이 똑같이 나오는 문제가 발생
QueryDSL이 인식되는것이 아니라 JPARespository로 계속 인식하는것 같다
@Repository
@RequiredArgsConstructor
public class ReservationRepositoryImple implements CustomRepository {
private final JPAQueryFactory jpaQueryFactory;
@Override
public List<Reservation> getReservationByUserIdOrItemId(Long userId, Long itemId) {
QReservation reservation = QReservation.reservation;
return jpaQueryFactory.select(reservation)
.from(reservation)
.innerJoin(reservation.user).fetchJoin()
.innerJoin(reservation.item).fetchJoin()
.where(reservation.user.id.eq(userId).and(reservation.item.id.eq(itemId)))
.fetch();
}
}
이름이 ReservationRepositiryImple을 ReservationRepositoryImpl로 고쳤다
그후 N+1도 해결하고 동적쿼리도 해결했다
이름하나 바꿔줬는데 문제는 해결되었지만 이유는 아직 찾지 못했다