* 동적쿼리문제
- 주문상태가 Order인것만 보여줘야함 // select * from * where ...
- 주문상태가 기본이면 상관없이 다 보여줘야함 // select * from * where X
class OrderRepository
해결1 : String 노가다
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();
}
단점 : 개발자실수가능성, 노가다성
해결2 : JPA표준 Criteria
/**
* 문제 : 동적쿼리?
* 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();
}
단점 : 무슨 SQL이 만들어질지 파악어려움 => 유지보수 어려움
해결3: 쿼리dsl
지금작동은 안된다. 추후강의에서 배워보자
public List<Order> findAll(OrderSearch orderSearch){
Order order=QOrder.order;
QMember member=Qmember.member;
return query
.select(order)
.from(order)
.join(order.member, member)
.where(statusEq(order.getOrderStatus()),
nameLike(orderSearch.getMemberName()))
.limit(1000)
.fetch();
}
private BooleanExpression statusEq(OrderStatus statusCond){
if(statusCond==null){
return null;
}
return order.status.eq(statusCond);
}
private BooleanExpression nameLike(String nameCond){
if(!StringUtils.hasText(nameCond)){
return null;
}
return member.name.like(nameCond);
}
'Java > Spring-app' 카테고리의 다른 글
회원등록 // get post mapping, 회원가입 오류처리, @Valid , @NotEmpty, BindingResult (0) | 2023.07.17 |
---|---|
홈화면과 레이아웃 // front, css매핑, 로그찍기 (0) | 2023.07.17 |
주문 기능 테스트 //@Test, Assert (0) | 2023.06.20 |
주문 서비스 개발 // 도메인 모델 패턴, 생성자제한, CASCADE, 변수 수정쿼리 (0) | 2023.06.13 |
주문 리포지토리 개발 (0) | 2023.06.13 |