220908 QueryDSL

Jongleee·2022년 9월 9일
1

TIL

목록 보기
48/737

QueryDSL

검색조건 쿼리

- List<Item> list = query.from(item)

			.where(item.name.eq("좋은상품").and(item.price().gt(20000)))

			.list(item);
-----------------------------------------------------
// ,는 and 취급
		    .where(item.name.eq("좋은상품"), (item.price().gt(20000)))

결과조회

- uniqueResult() : 한건, 없으면 null, 하나이상이면 예외

- singleResult() : 한건, 없으면 null, 하나이상이면 처음 데이터 반환

- list() : 하나이상, 없으면 빈 컬렉션

페이징과 정렬

-orderBy(item.price().desc(), item.stockQuantitiy.asc()).

- offset(10).limit(20)

- list()

- SearchResult<Item> result = query.from(item)
								.where
							    ....
							    .listResults(item)

- long total = result.getTotal();

- long limit = result.getLimit();

- long offset = result.getOffset();

- List<Item> results = result.getResult;

그룹

- groupBy(item.price)

- having(item.price.gt(1000))

- list()

조인

- innerJoin(), leftJoin(), rightJoin(), fullJoin(), JPQL의 on, fetch 사용 가능

- join(조인대상, 별칭으로 사용할 쿼리 타입)		

- innerJoin(order.member, member).fetch()

- leftJoin(order.orderItems, orderItem).fetch()

          .on(orderItem.count.gt(2)) // on 사용 가능
  • 세타조인
	- query.from(order, member)
			.where(order.member.eq(member))
			.list()

서브쿼리

- QItem item = QItem.item
		  QItem itemSub = new QItem("itemSub")


		  query.from(item)
		       .where(item.price.eq(new JPASubQuery().from(itemSub).unique(itemSub.price.max()))) // 한 건이면 unique
		       .list()


		  query.from(item)
		       .where(item.in(new JPASubQuery().from(itemSub).where(item.name.eq(itemSub.name).list(itemSub))) // 여러 건이면 list
		       .list()

프로젝션 결과 반환

  • 대상이 하나
	QItem item = QItem.item
	List<String> result = query.from(item).list(item.name)
  • 대상이 여러개
	QItem item = QItem.item

	List<Tuple> result = query.from(item).list(item.name, item.price);

빈 생성 : 쿼리결과를 엔티티가 아닌 특정 객체로 받을 수 있다

  • 프로퍼티 접근(Setter)
	QItem item = QItem.item
	List<ItemDTO> result = query.from(item).list(
	Projections.bean(ItemDTO.class, item.name.as("username"), item.price));
  • 필드 직접접근 : 필드를 private 로 설정해도 동작한다
	QItem item = QItem.item
    List<ItemDTO> result = query.from(item).list(
    Projections.fields(ItemDTO.class, item.name.as("username"), item.price));
  • 생성자 사용
	QItem item = QItem.item
	List<ItemDTO> result = query.from(item).list(
	Projections.constructor(ItemDTO.class, item.name, item.price));

DISTINCT

 query.distinct().from(item)...

수정, 삭제 배치 쿼리

  • 수정 : JPAUpdateClause
	QItem item = QItem.item
	JPAUpdateClause updateClause = new JPAUpdateClause(em, item)
	long count = updateClause.where(item.name.eq("상품명"))
		  .set(item.price, item.price.add(100))
 		  .execute();

-##### 삭제 : JPADeleteClause

	QItem item = QItem.item
	JPADeleteClause deleteClause = new JPADeleteClause(em, item)
	long count = deleteClause.where(item.name.eq("상품명")).execute();

동적쿼리

	BooleanBuilder builder = new BooleanBuilder();
	if(param.getPrice() != null){
		  builder.and(item.price.gt(param.getPrice()));
	}
	List<Item> result = query.from(item)
		  					.where(builder)
		  					.list(item)

메소드 위임

  • 쿼리 타입(Q 로 만들어진 클래스)에 검색 조건을 직접 정의 할 수 있다

네이티브 SQL

  • JPQL 로 작성하기 어려운 복잡한 SQL쿼리를 작성하거나 SQL을 최적화 할 경우 사용 => 어노테이션 보다는 XML 로 사용하는 것이 더 편리함

  • Query, TypeQuery(@NamedNativeQuery 만) 를 반환한다 => JPQL API 를 그대로 사용할 수 있다

  • 특정 데이터베이스만 지원하는 함수, 문법, SQL 쿼리 힌트

  • 인라인 뷰(from 절에서 사용하는 서브쿼리), UNION, INTERSECT

  • 스토어드 프로시저

  • 엔티티를 조회할 수 있고 JPA 가 지원하는 영속성 컨텍스트의 기능을 그대로 이용할 수 있다

	Query nativeQuery = em.createNativeQuery(strSql, Member.class).setParameter(1,20)
	List<Member> result = nativeQuery.getResultList();
  • 스칼라식 조회
	Query nativeQuery = em.createNativeQuery(strSql).setParameter(1,20)
	List<Object[]> result = nativeQuery.getResultList();
  • 스칼라는 엔티티가 아니므로 영속성 컨텍스트가 관리하지 않는다 => JDBC 가 데이터를 조회한 것과 비슷하다

0개의 댓글