[스프링 활용] 주문 검색 기능 (ing)

atdawn·2024년 6월 13일

SPRING BOOT+JPA

목록 보기
27/49

참고 : 인프런 [ 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 김영한 ]


구현 기능 중 주문 목록에서 회원명과 주문 상태로 필터링하여 조회하는 기능이 있다.
이것은 동적 쿼리로 구현해야한다.

우선 검색 조건 파라미터 클래스를 생성하자

package jpabook.jpashop.repository;

@Getter @Setter
public class OrderSearch {

    private String memberName; //회원 이름
    private OrderStatus orderStatus; //주문 상태[ORDER, CANCEL]
}

검색 조건에 동적으로 쿼리를 생성해서 주문 엔티티를 조회 메서드

public List<Order> findAll(OrderSearch orderSearch) {
        return em.createQuery("select o from Order o join o.member m" +
                " where o.status =:status " +
                " and m.name like :name", Order.class)
                .setParameter("status",orderSearch.getOrderStatus())
                .setParameter("name",orderSearch.getMemberName())
                .setMaxResults(1000) //최대 1000개까지 조회
                .getResultList();

    }
  • 위 코드는 무조건 필터 조건으로 주문상태와, 회원 이름이 필요하다.
  • 주문 상태와 회원 이름이 없을 때는 모든 목록을 조회하도록 구현하려면 어떻게 해야 할까?

1. JPQL 로 구현 (비추)

public List<Order> findAllByString(OrderSearch orderSearch) {
     //language=JPAQL
     String jpql = "select o From Order o join o.member m";
     boolean isFirstCondition = true;
//주문 상태 검색
if (orderSearch.getOrderStatus() != null) {
         if (isFirstCondition) {
             jpql += " where";
             isFirstCondition = false;
         } else {
             jpql += " and";
}
         jpql += " o.status = :status";
     }
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
         if (isFirstCondition) {
             jpql += " where";
             isFirstCondition = false;
         } else {
             jpql += " and";
}
         jpql += " m.name like :name";
     }
TypedQuery<Order> query = em.createQuery(jpql, Order.class) .setMaxResults(1000); //최대 1000건
     if (orderSearch.getOrderStatus() != null) {
         query = query.setParameter("status", orderSearch.getOrderStatus());
     }
     if (StringUtils.hasText(orderSearch.getMemberName())) {
         query = query.setParameter("name", orderSearch.getMemberName());
     }
     return query.getResultList();
 }
  • JPQL 쿼리를 문자로 생성하기는 번거롭고, 실수로 인한 버그가 충분히 발생할 수 있다.
  • 유지 보수에 최악

2. JPA Criteria로 처리 (비추)

public List<Order> findAllByCriteria(OrderSearch orderSearch) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> o = cq.from(Order.class);
Join<Order, Member> m = o.join("member", JoinType.INNER); //회원과 조인
     List<Predicate> criteria = new ArrayList<>();
//주문 상태 검색
if (orderSearch.getOrderStatus() != null) {
         Predicate status = cb.equal(o.get("status"),
 orderSearch.getOrderStatus());
         criteria.add(status);
     }
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
         Predicate name =
                 cb.like(m.<String>get("name"), "%" + orderSearch.getMemberName()
 + "%");
         criteria.add(name);
}
     cq.where(cb.and(criteria.toArray(new Predicate[criteria.size()])));
TypedQuery<Order> query = em.createQuery(cq).setMaxResults(1000); //최대 1000 건
     return query.getResultList();
 }
  • Criteria 는 JPA 표준 스펙이지만 실무에서 사용하기에는 복잡하다.

3. Querydsl 사용 (추천)

추후...강의에서..설명...

profile
복습 복습 복습

0개의 댓글