[Spring Database] QueryDSL
QueryDSL (Query Domain Specific Language) 특정 도메인에 초점을 맞춘 프로그래밍 언어이다.
쿼리에 특화된 프로그래밍 언어이고, JPA / MongoDB / SQL 같은 데이터베이스 관련 기술들을 사용할 때 쿼리를 type-safe하게 개발 할 수 있게 지원하는 프레임워크이다.
Entity 혹은 데이터베이스의 테이블의 정보를 바탕으로 QueryDSL Annotation Processing Tool 를 사용해 쿼리 전용 멤버 객체인 Q(Entity이름).java 를 만든다. (생성된 객체를 바탕으로 쿼리를 자바 코드로 작성한다)
즉, Q().java 파일을 사용해 자바 코드를 작성하고, 작성된 자바 코드는 JQPL로 변환되고 JQPL은 SQL로 변환돼서 실행된다.
@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 = findById(itemId).orElseThrow();
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 itemSearch) {
String itemName = itemSearch.getItemName();
Integer maxPrice = itemSearch.getMaxPrice();
QItem item = QItem.item;
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();
List<Item> result = query
.select(item)
.from(item)
.where(likeItemName(itemName), maxPrice(maxPrice))
.fetch();
return result;
}
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은 JPQL을 만드는 공장이다.
JPAQueryFactory가 있어야 QueryDSL을 사용할 수 있다.
JPAQueryFactory는 JPQL을 만들기 때문에 EnityManager가 필요하다.
두 가지 모두 주입받아서 사용하자.
간단한 작업은 QueryDSL 기술을 사용하지 않아도 쉽게 처리할 수 있다. JPA가 제공하는 기본 기능을 사용해 처리하자.
BooleanBuilder를 사용해 원하는 조건들을 추가할 수 있다. (조건이 여러 개면 and로 묶인다)
직관적으로 코드를 이해할 수 있고, 컴파일 시점에서 에러를 확인할 수 있으며 쿼리를 조각내서 다른 쿼리를 작성할 때 모듈로 사용할 수 있고, 자바 코드로 작성하기 때문에 상황에 맞춰 동적 쿼리를 쉽게 작성하는 등 자바 코드를 사용해서 얻을 수 있는 장점을 모두 얻는다.
QueryDSL은 이 외에도 페이징 기능, DTO를 사용한 조회 등 여러 가지 편리한 기능을 제공한다.
'Spring > Spring Database' 카테고리의 다른 글
[Spring Database] 트랜잭션 전파 (1) | 2022.09.16 |
---|---|
[Spring Database] 트랜잭션 (0) | 2022.09.13 |
[Spring Database] Spring Data JPA (0) | 2022.09.11 |
[Spring Database] JPA 적용 (0) | 2022.09.10 |
[Spring Database] JPA (1) | 2022.09.09 |
댓글
이 글 공유하기
다른 글
-
[Spring Database] 트랜잭션 전파
[Spring Database] 트랜잭션 전파
2022.09.16 -
[Spring Database] 트랜잭션
[Spring Database] 트랜잭션
2022.09.13 -
[Spring Database] Spring Data JPA
[Spring Database] Spring Data JPA
2022.09.11 -
[Spring Database] JPA 적용
[Spring Database] JPA 적용
2022.09.10