[Spring] 스프링 DB 2편 07

알재·2023년 12월 6일

스프링 DB

목록 보기
13/17

김영한님의 스프링 DB 2편 을 공부하여 정리한 글입니다.

Querydsl 적용

Repository

@Repository
@Transactional
public class JpaItemRepositoryV3 implements ItemRepository {

    private final EntityManager em;
    private final JPAQueryFactory query;

    public JpaItemRepositoryV3(EntityManager em) {
        this.em = em;
        this.query = new JPAQueryFactory(em);
    }

    @Override
    public Item save(Item item) {
        em.persist(item);
        return item;
    }

    @Override
    public void update(Long itemId, ItemUpdateDto updateParam) {
        Item findItem = em.find(Item.class, itemId);
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
    }

    @Override
    public Optional<Item> findById(Long id) {
        Item item = em.find(Item.class, id);
        return Optional.ofNullable(item);
    }

    public List<Item> findAllOld(ItemSearchCond cond) {

        String itemName = cond.getItemName();
        Integer maxPrice = cond.getMaxPrice();

        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.hasText(itemName)) {
            builder.and(item.itemName.like("%" + itemName + "%"));
        }
        if (maxPrice != null) {
            builder.and(item.price.loe(maxPrice));
        }

        List<Item> result = query.select(item)
                .from(item)
                .where(builder)
                .fetch();

        return result;
    }

    @Override
    public List<Item> findAll(ItemSearchCond cond) {

        String itemName = cond.getItemName();
        Integer maxPrice = cond.getMaxPrice();

        return query
                .select(item)
                .from(item)
                .where(likeItemName(itemName), maxPrice(maxPrice))
                .fetch();
    }

    private BooleanExpression likeItemName(String itemName) {
        if (StringUtils.hasText(itemName)) {
            return item.itemName.like("%" + itemName + "%");
        }
        return null;
    }

    private BooleanExpression maxPrice(Integer maxPrice) {
        if (maxPrice != null) {
            return item.price.loe(maxPrice);
        }
        return null;
    }
}
  • Querydsl을 사용하려면 JPAQueryFactory 가 필요하다.
    JPAQueryFactory 는 JPA 쿼리인 JPQL을 만들기 때문에 EntityManager 가 필요하다.

findAllOld()

  • Querydsl을 사용해서 동적 쿼리 문제를 해결한다.
  • BooleanBuilder 를 사용해서 원하는 where 조건들을 넣어주면 된다.

findAll()

  • Querydsl에서 where(A,B) 에 다양한 조건들을 직접 넣을 수 있는데,
    이렇게 넣으면 AND 조건으로 처리된다.
    참고로 where() 에 null 을 입력하면 해당 조건은 무시한다.

Querydsl 장점

  • 쿼리 문장에 오타가 있어도 컴파일 시점에 오류를 막을 수 있다.
  • 메서드 추출을 통해서 코드를 재사용할 수 있다.
    예를 들어서 여기서 만든 likeItemName(itemName) , maxPrice(maxPrice) 메서드를 다른 쿼리에서도 함께 사용할 수 있다.
profile
저장소

0개의 댓글