소스코드로 query를 생성하는 방식
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>5.0.0</version>
</dependency>
...
...
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
@Autowired
ItemRepository itemRepository;
@PersistenceContext
EntityManager em;
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QItem qItem = QItem.item;
JPAQuery<Item> query = queryFactory.selectFrom(qItem)
.where(qItem.itemSellStatus.eq(ItemSellStatus.SELL))
.where(qItem.itemDetail.like("%테스트 상품 상세 설명%"))
.orderBy(qItem.price.desc());
List<Item> itemList = query.fetch();
@PersistenceContext
로 EntityManager
빈을 주입JPAQueryFactory
를 이용하여 query를 동적으로 생성Querydsl
을 통해 쿼리를 생성하기 위해 Q class 객체 이용fetch
메소드를 이용하여 query 결과를 리스트로 반환method | description |
---|---|
List<T> fetch() | 조회 대상들을 리스트로 반환 |
QueryResults<T> fetchResults() | 조회 대상 리스트 및 개수를 포함한 결과 QueryResults 반환 |
T fetchOne() | 조회 대상이 1개이면 반환, 1개가 아니면 에러 발생 |
T fetchFirst() | 조회 대상이 1개 이상이면 첫번째 대상 반환 |
Long fetchCount() | 조회 대상들의 전체 개수 반환 |
public interface ItemRepositoryCustom {
Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable);
Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable);
}
itemSearchDto
객체와 페이징 정보를 담고 있는 pageable
객체를 인자로 받음Page
객체로 반환public class ItemRepositoryCustomImpl implements ItemRepositoryCustom {
private JPAQueryFactory queryFactory;
public ItemRepositoryCustomImpl(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
...
}
JPAQueryFactory
클래스를 사용하고, 생성자로 EntityManager
객체를 전달public class ItemRepositoryCustomImpl implements ItemRepositoryCustom {
...
private BooleanExpression regDtsAfter(String searchDateType) {
LocalDateTime dateTime = LocalDateTime.now();
if (StringUtils.equals("all", searchDateType) || searchDateType == null) {
return null;
} else if (StringUtils.equals("1d", searchDateType)) {
dateTime = dateTime.minusDays(1);
} else if (StringUtils.equals("1w", searchDateType)) {
dateTime = dateTime.minusWeeks(1);
} else if (StringUtils.equals("1m", searchDateType)) {
dateTime = dateTime.minusMonths(1);
} else if (StringUtils.equals("6m", searchDateType)) {
dateTime = dateTime.minusMonths(6);
}
return QItem.item.regTime.after(dateTime);
}
private BooleanExpression searchByLike(String searchBy, String searchQuery) {
if (StringUtils.equals("itemNm", searchBy)) {
return QItem.item.itemNm.like("%" + searchQuery + "%");
} else if (StringUtils.equals("createdBy", searchBy)) {
return QItem.item.createdBy.like("%" + searchQuery + "%");
}
return null;
}
private BooleanExpression itemNmLike(String searchQuery) {
return StringUtils.isEmpty(searchQuery) ? null : QItem.item.itemNm.like("%" + searchQuery + "%");
}
@Override
public Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
QueryResults<Item> results = queryFactory
.selectFrom(QItem.item)
.where(searchSellStatusEq(itemSearchDto.getSearchSellStatus()),
regDtsAfter(itemSearchDto.getSearchDateType()),
searchByLike(itemSearchDto.getSearchBy(), itemSearchDto.getSearchQuery()))
.orderBy(QItem.item.id.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetchResults();
List<Item> content = results.getResults();
long total = results.getTotal();
return new PageImpl<>(content, pageable, total);
}
@Override
public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
QItem item = QItem.item;
QItemImg itemImg = QItemImg.itemImg;
QueryResults<MainItemDto> results = queryFactory
.select(new QMainItemDto(item.id, item.itemNm, item.itemDetail, itemImg.imgUrl, item.price))
.from(itemImg)
.join(itemImg.item, item)
.where(itemImg.repImgYn.eq("Y"))
.where(itemNmLike(itemSearchDto.getSearchQuery()))
.orderBy(item.id.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetchResults();
List<MainItemDto> content = results.getResults();
long total = results.getTotal();
return new PageImpl<>(content, pageable, total);
}
}
public interface ItemRepository extends JpaRepository<Item, Long>, QuerydslPredicateExecutor<Item>, ItemRepositoryCustom {
...
}
@Service
@Transactional
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
@Transactional(readOnly = true)
public Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable){
return itemRepository.getAdminItemPage(itemSearchDto, pageable);
}
@Transactional(readOnly = true)
public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
return itemRepository.getMainItemPage(itemSearchDto, pageable);
}
}