public interface CarRepository extends JpaRepository<Car, Long>{
@Query("select c from Car c join fetch c.location where c.user.id = :userId and c.number like %:number")
List<Car> findByLastFourNumbers(@Param("userId") Long userId, @Param("number") String number);
@Query("select c from Car c join fetch c.location where c.user.id = :userId")
List<Car> findByUserId(@Param("userId") Long userId);
}
public interface CarRepositoryCustom{
List<CarDto> search(CarSearchCondtion condition);
}
Query Dsl 를 작성과 유지보수를 쉽게하기 위해서 Custom을 만들어줍니다.
⚠️주의. 이름 지을 때 해당하는 repository 이름+ Impl를 붙혀서 이름을 지어준다.
public class CarRepositoryImpl implements CarRepositoryCustom{
// 쿼리문을 작성을 위해 선언
private final JPAQueryFactory queryFactory;
// 생성자 주입
public CarRepositoryImpl(EntityManager em){
this.queryFactory = new JPAQueryFactory(em);
}
@Override
public List<CarDto> search(CarSearchCondition condition){
return queryFactory
.select(Projections.fields(CarDto.class,
car.id, //QCar.car(Qcar를 static 시킴)
car.number,
car.user.username,
car.address,
car.location.lat,
car.location.lng
))
.from(car)
.leftJoin(car.user, user)
.where(
usernameEq(condition.getUsername()),
targetEq(condtion.getTarget())
.fetch();
}
private BooleanExpression usernameEq(String username){
return StringUtils.hasText(username) ? car.user.username.eq(username) : null;
}
private BooleanExpression targetEq(String target){
return StringUtils.hasText(target) && target.length() >= 4 ? car.number.endWith(target) : null;
}
}
동적쿼리 작성하는 방법은 2가지 방법이 있습니다.
1. BooleanBuilder
2. where 다중 파라미터 사용
public void BooleanBuilder() throws Exception{ String usernameParam = "member1"; Integer ageParam = 10; BooleanBuilder builder = new BooleanBuilder(); if(usernameCond != null){ builder.and(member.username.eq(usernameCond)); } if(ageCond != null){ builer.and(member.age.eq(ageCond)); } List<Member> result = queryFactory .selectFrom(member) .where(builder) .fetch(); }
where 다중 파라미터는
1. where 조건에 null 값은 무시되는 장점
2. 메서드를 다른 쿼리에서도 재활용 할 수 있는 장점
3. 쿼리 자체의 가독성이 높아지는 장점
위와 같은 3가지 장점이 있어 선택하였습니다.
public interface CarRepository extends JpaRepository<Car, Long>, CarRepositoryCustom{
}
JPQL 작성한 코드는 삭제하고 인터페이스로 만든 CarRespositoryCustom을 상속받아줍니다.
링크
Inflearn의 김영한님 실전! Querydsl 강의입니다.
잘못된 내용이 있으면 알려주세요. 댓글 남겨주세요!! 수정하겠습니다!!