728x90

분류 전체보기 331

페이징과 정렬(feat.queryDSL)

QItem item = QItem.item; query.from(item) .where(item.price.gt(20000) .orderBy(item.price.desc(), item.stockQuantity.asc()) .offset(10).limit(20) .list(item); 정렬은 orderBy를 사용하는데 쿼리 타입(Q)이 제공하는 asc(), desc()를 사용한다. 페이징은 offset과 limit을 적절히 조합해서 사용하면 된다. 실제 페이징 처리를 하려면 검색된 전체 데이터 수를 알아야 한다. 이때는 list() 대신에 아래 예제와 같이 listResults()를 사용한다. SearchResults result = query.from(item) .where(item.price.gt(10..

QueryDSL 2022.06.17

검색 조건 쿼리(feat. QueryDSL)

JPAQuery query = new JPAQuery(em); //검색 조건 쿼리 실행 QItem item = QItem.item; List list = query.from(item) .where(item.name.eq("좋은상품").and(item.price.gt(20000))) .list(item); //조회할 프로젝션 지정 select item --실행된 JPQL from Item item where item.name ?1 and item.price > ?2 QueryDSL의 where 절에는 and 나 or을 사용할 수 있다. 또한 다음처럼 여러 검색 조건을 사용해도 된다. 이때는 and 연산이 된다. .where(item.name.eq("좋은 상품"), item.price.gt(20000)) 쿼..

QueryDSL 2022.06.17

기본 Q 생성

쿼리 타입(Q)은 사용하기 편하도록 아래와 같이 기본 인스턴스를 보관하고 있다. 하지만 같은 엔티티를 조인하거나 같은 엔티티를 서브쿼리에 사용하면 같은 별칭이 사용되므로 이때는 별칭을 직접 지정해서 사용해야 한다. public class QMember extends EntityPathBase { public static final QMember member = new QMember("member1"); ... } QMember qMember = new QMember("m"); //직접 지정 QMember qMember = QMember.member; //기본 인스턴스 사용 쿼리 타입의 기본 인스턴스를 사용하면 아래와 같이 import static을 활용해서 코드를 더 간결하게 작성할 수 있다. impor..

QueryDSL 2022.06.17

컬렉션 엔티티 조회 + 페이징을 함께 해결 (feat. default_batch_fetch_size)

먼저 ToOne(OneToOne, ManyToOne) 관계를 모두 페치조인 한다. ToOne 관계는 row수를 증가시키지 않으므로 페이징 쿼리에 영향을 주지 않는다. 컬렉션은 지연 로딩으로 조회한다. 지연 로딩 성능 최적화를 위해 hibernate.default_batch_fetch_size , @BatchSize 를 적용한다. hibernate.default_batch_fetch_size: 글로벌 설정 - 이 옵션을 사용하면 컬렉션이나, 프록시 객체를 한꺼번에 설정한 size 만큼 IN 쿼리로 조회한다. @Repository public class OrderRepository { public List findAllWithMemberDelivery(int offset, int limit) { return..

JPA 2022.06.16

QueryDSL(Criteria 보다 더 나은 JPQL 빌더)

쿼리를 문자가 아닌 코드로 작성해도, 쉽고 간결하며 그 모양도 쿼리와 비슷하게 개발할 수 있는 프로젝트가 바로 QueryDSL이다. QueryDSL도 Criteria처럼 JPQL 빌더 역할을 하는데 JPA Criteria를 대체할 수 있다. QueryDSL 설정 .... com.mysema.maven apt-maven-plugin 1.1.3 process target/generated-sources/java com.querydsl.apt.jpa.JPAAnnotationProcessor .... com.querydsl querydsl-apt ${querydsl.version} provided com.querydsl querydsl-jpa ${querydsl.version} querydsl-jpa: Quer..

JPA 2022.06.16

Criteria 기초(feat. JPQL의 빌더 클래스)

Criteria 쿼리는 JPQL을 자바 코드로 작성하도록 도와주는 빌더 클래스 API다. Criteria를 사용하면 문자가 아닌 코드로 JPQL을 작성하므로 문법 오류를 컴파일 단계에서 잡을 수 있고 문자 기반의 JPQL보다 동적 쿼리를 안전하게 생성할 수 있는 장점이 있다. 하지만 실제 Criteria를 사용해서 개발해보면 코드가 복잡하고 장황해서 직관적으로 이해가 힘들다는 단점도 있다. //JPQL: select m from Member m CriteriaBuilder cb = em.getCriteriaBuilder(); //Criteria 쿼리 빌더 ...1 //Criteria 생성, 반환 타입 지정 ...2 CriteriaQuery cq = cb.createQuery(Member.class); R..

JPA 2022.06.16

페치 조인과 일반 조인의 차이(feat. 연관된 엔티티 함께 조회)

페치 조인을 사용하지 않고 조인만 사용하면 어떻게 될까 select t-- 내부 조인 JPQL from Team t join t.members m where t.name = '팀A' SELECT--실행된 SQL T.* FROM TEAM T INNER JOIN MEMBER M ON T.ID=M.TEAM_ID WHERE T.NAME = '팀A' JPQL에서 팀과 회원 컬렉션을 조인했으므로 회원 컬렉션도 함께 조회할 것으로 기대해선 안 된다. 실행된 SQL의 SELECT 절을 보면 팀만 조회하고 조인했던 회원은 전혀 조회하지 않는다. JPQL은 결과를 반환할 때 연관관계까지 고려하지 않는다. 단지 SELECT 절에 지정한 엔티티만 조회할 뿐이다. 따라서 팀 엔티티만 조회하고 연관된 회원 컬렉션은 조회하지 않는..

JPA 2022.06.15

페이징 API

JPA는 페이징을 다음 두 API로 추상화했다. setFirstResult(int startPosition): 조회 시작 위치(0부터 시작한다) setMaxResults(int maxResult): 조회할 데이터 수 TypedQuery query = em.createQuery("SELECT m FROM Member m ORDER BY m.username DESC", Member.class); query.setFirstResult(10); query.setMaxResults(20); query.getResultList(); 위 코드를 분석하면 FirstResult의 시작은 10이므로 11번째부터 시작해서 총 20건의 데이터를 조회한다. 따라서 11~30번 데이터를 조회한다. 또한, 데이터베이스마다 다른 페..

JPA 2022.06.15

프로젝션 NEW 명령어

바로 밑의 예제는 username, age 두 필드를 프로젝션해서 타입을 지정할 수 없으므로 TypeQuery를 사용할 수 없다. 따라서 Object[]를 반환받았다. List resultList = em.createQuery("SELECT m.username, m.age FROM Member m") .getResultList(); //객체 변환 작업 List userDTOs = new ArrayList(); for (Object[] row : resultList) { UserDTO userDTO = new UserDTO((String)row[0], (Integer)row[1]); userDTOs.add(userDTO); } return userDTOs; public class UserDTO { priv..

JPA 2022.06.14

객체지향 쿼리 소개(feat. JPQL)

EntityManager.find() 메소드를 사용하면 식별자로 엔티티 하나를 조회할 수 있다. 이렇게 조회한 엔티티에 객체 그래프 탐색을 사용하면 연관된 엔티티들을 찾을 수 있다. 이 둘은 가장 단순한 검색 방법이다. 식별자로 조회 EntityManager.find() 객체 그래프 탐색(예: a.getB().getC()) ORM을 사용하면 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 개발하므로 검색도 테이블이 아닌 엔티티 객체를 대상으로 하는 방법이 필요하다. JPQL은 이런 문제를 해결하기 위해 만들어졌는데 다음과 같은 특징이 있다. 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리다. SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. JPQL은 엔티티 객체를 대상으로 하는 객..

JPA 2022.06.14
728x90