Querydsl은 엔티티로 설정된 모델 클래스와 동일한 패키지에 "Q" 모델이라는 쿼리타입 클래스를 미리 생성해 놓고 메타데이터로 사용하여 쿼리를 메소드 기반으로 작성합니다. Querydsl을 사용하면 보다 쉽고 직관적으로 처리할 수 있습니다.
쿼리문을 작성하기 위해서 모두 Q 타입 클래스를 사용합니다.
JPAQuery, JPAQueryFactory 클래스를 사용하면 EntityManager를 통해서 질의가 처리되고 이 때 사용하는 쿼리문은 JPQL 입니다.
SQLQuery, SQLQueryFactory 클래스를 사용하면 JDBC 기술을 사용하여 질의가 처리되고 이 때 사용하는 쿼리문은 SQL입니다.
JPASQLQuery 클래스를 사용하면 EntityManager를 통해서 질의가 처리되고 이 때 사용하는 쿼리문은 SQL입니다. 추가적으로 EntityManager를 이용하고 싶을 때 사용합니다.
(스프링, JPA강좌)JPA에서 사용하는 Querydsl 구문종류_JPAQuery, JPAQuery, JPASQLQuery, SQLQuery, SQLQueryFactory
1. 3.2. Querydsl 의 종류_JPA 에서 Querydsl
사용하는 방법의 종류
www.topcredu.co.kr
Q u e r y d s l 은 엔티티로 설정된 모델 클래스와 동일한 패키지에
" Q " 모델이라는 쿼리타입 클래스를 미리 생성해 놓고
메타데이터로 사용하여 쿼리를 메소드 기반으로 작성합니다.
Q u e r y d s l 을 사용하면 보다 쉽고 직관적으로 처리할 수
있습니다.
3.2.1. Querydsl 구분
Thread Safe
as
Bean(Singleton)
Use
EntityManager
(First Caching)
Use Entity
Class
JPAQuery new v v
JPAQueryFactory v v v
JPASQLQuery new
v (No First
Caching)
Table
2. SQLQuery new DataSource Table
SQLQueryFactory v DataSource Table
쿼리문을 작성하기 위해서 모두 Q 타입 클래스를 사용합니다.
JPAQuery, JPAQueryFactory 클래스를 사용하면 EntityManager
를 통해서 질의가 처리되고 이 때 사용하는 쿼리문은 JPQL 입니다.
SQLQuery, SQLQueryFactory 클래스를 사용하면 JDBC 기술을
사용하여 질의가 처리되고 이 때 사용하는 쿼리문은 SQL 입니다.
JPASQLQuery 클래스를 사용하면 EntityManager 를 통해서 질의
가 처리되고 이 때 사용하는 쿼리문은 SQL 입니다. 추가적으로
EntityManager 를 이용하고 싶을 때 사용합니다.
3. 3.2.2. 엔티티 클래스를 만들어서 사용
" Q " 모델은 클래스 내 자체적으로 이미 인스턴스를 s t a t i c
변수로 가지고 있기 때문에 예를 들어 " Q E m p . e m p " 처럼
간단하게 사용할 수 있습니다.
1. JPAQuery
QEmp emp = QEmp.emp;
JPAQuery query = new JPAQuery(em);
query.select(emp).from(emp).where(emp.ename.eq("SMITH
"));
List<Emp> result = query.fetch();
JPAQuery 생성자에 EntityManager 객체를 전달합니다.
select 메소드는 얻고자 하는 칼럼들을 지정하는
P r o j e c t i o n 설정용입니다.
from 메소드는 쿼리대상을 지정합니다.
where 메소드는 쿼리 조건을 적용하는 필터입니다.
fetch 메소드로 복수의 로우 데이터를 얻을 수 있습니다.
대부분의 데이터베이스는 저장하는 정보를 필터링할 때 대소문자를
구분하기 때문에 " S M I T H " 문자열을 소문자로 사용하면 해당
데이터가 없다고 할 것이니 주의가 필요합니다.
2. JPAQueryFactory
JPAQueryFactory queryFactory = new
JPAQueryFactory(em);
List<Emp> emps =
queryFactory.selectFrom(emp).where(emp.ename.eq("SMIT
H")).fetch();
4. J P A Q u e r y F a c t o r y 로 J P A Q u e r y 를 만들어서
사용하는 방식입니다. J P A Q u e r y F a c t o r y 를 빈
컨테이너에 등록해 놓고 D I 받아 사용하면 편리합니다.
J P A Q u e r y F a c t o r y 는
J P Q L Q u e r y F a c t o r y 인터페이스를 구현했으며
J P A Q u e r y 인스턴스를 포함하여 다양한 방법으로 쿼리 할 수
있습니다. 생성할 때 E n t i t y M a n a g e r 만 인자로 넣어
생성할 수도 있고 J P Q L T e m p l a t e 도 같이 인자로 줘서
생성 할 수 있습니다. 다이나믹하게 데이터베이스가 바뀌는 경우는
거의 없기 때문에 보통 J P Q L T e m p l a t e 은 생략하고
사용합니다.
selectFrom(emp) 메소드는
select( e m p ) . f r o m ( e m p ) 선언의 축약형태입니다.
eq 메소드는 " = " 연산자를 대체하는 메소드입니다.
3.2.3. 엔티티 클래스를 만들지 않고 사용
1. JPASQLQuery
엔티티 클래스를 만들지 않고 사용할 수 있습니다. 엔티티 클래스를
작성한 후 이를 바탕으로 테이블을 구성하여 진행하는 개발방식 대신
이미 테이블이 존재하는 경우 이를 바탕으로 쿼리타입을 생성하여
질의할 때 이용하는 방식입니다.
이는 엔티티매니저의 c r e a t e N a t i v e Q u e r y 메소드를
사용하는 것과 결과가 같습니다. 하지만 둘 사이에는 큰 차이가
존재합니다.
J P A S Q L Q u e r y 클래스를 사용하거나
e m . c r e a t e N a t i v e Q u e r y 메소드를 사용하거나 둘
5. 다 개발자가 지정해서 알려 준 쿼리를 사용합니다.
e m . c r e a t e N a t i v e Q u e r y 에서 파라미터로 넘겨주는
모델클래스는 엔티티이므로 여러 엔티티 클래스의 연관관계에 따른
E A G E R 로딩정책을 지키기 위해서 추가적으로 쿼리가 더 수행될
수 있습니다.
하지만 new JPASQLQuery<Void>(em, templates) 코드에서 보는
것처럼 엔티티매니저를 사용한다고 하더라도 엔티티 클래스를 알려
준 것은 아니므로 연관관계에 따른 추가적인 쿼리가 수행되지
않는다는 차이점이 존재합니다. 더불어 엔티티 클래스를 이용한
것이 아니므로 1 차 캐싱기능을 이용하지 못합니다. 질의를 하면
엔티티매니저가 매번 데이터베이스에 질의하여 데이터를 얻어다 줄
것입니다.
J P A Q u e r y 객체로는 인라인뷰 쿼리를 작성하지 못합니다.
따라서 인라인뷰를 사용하고자 하는 경우에는 대신
J P A S Q L Q u e r y 를 사용해야 합니다. 인라인뷰를 사용하지
못하는 것은 Q u e r y d s l 의 한계가 아니라 J P A 의 기술적인
한계입니다.
J P A S Q L Q u e r y 를 사용하기 위해서 우선 테이블을 바탕으로
리버스 엔지니어링을 진행하여 쿼리타입 클래스를 생성해야 합니다.
이 때 필요하다면 모델 클래스를 같이 생성할 수 있습니다. 메이븐
설정에 q u e r y d s l - m a v e n - p l u g i n 을 추가하여 Q
타입 클래스를 생성한 다음 이용합니다.
SQLTemplates templates = new DerbyTemplates();
QEmp emp = new QEmp("emp");
JPASQLQuery<?> query = new JPASQLQuery<Void>(em,
templates);
List<Tuple> rows = query.select(emp.empno,
emp.ename).from(emp)
.where(emp.ename.eq("SMITH").fetch();
6. S Q L T e m p l a t e s 의 구현체는 데이터베이스에 따라서
선택해서 사용합니다. 선택된 구현체를 파라미터로 전달하고
사용해야 하는 D i a l e c t 를 판단하는 용도로 사용됩니다.
2. SQLQuery
S Q L Q u e r y 를 직접 사용하는 방법보다는
S Q L Q u e r y F a c t o r y 를 통해서 사용하는 방법을
권장합니다. 따라서 S Q L Q u e r y F a c t o r y 를 사용하는
방법을 바로 살펴 보겠습니다.
3. SQLQueryFactory
SQLTemplates templates = new MySQLTemplates();
Configuration configuration = new
Configuration(templates);
SQLQueryFactory queryFactory = new
SQLQueryFactory(configuration, dataSource);
QEmp emp = new QEmp("emp");
List<Emp> result =
queryFactory.selectFrom(emp).where(emp.ename.eq("SMIT
H")).fetch();
S Q L Q u e r y F a c t o r y 생성자에 설정정보인
C o n f i g u r a t i o n 과 데이터베이스 연결정보인
D a t a S o u r c e 를 주고 있습니다. 따라서 엔티티매니저를
거쳐서 사용하는 것이 아닌 개발자가 직접 데이터베이스가 이해하는
S Q L 을 작성한 다음 J D B C 기술을 사용하여 처리하는
방식이라는 것을 알 수 있습니다.
다음은 이해를 돕기위한
c o m . q u e r y d s l . s q l . A b s t r a c t S Q L Q u e r
y . f e t c h 메소드 소스의 일부분 입니다.
7. //… 생략
final PreparedStatement stmt =
getPreparedStatement(queryString);
try {
setParameters(stmt, constants,
serializer.getConstantPaths(),
queryMixin.getMetadata().getParams());
context.addPreparedStatement(stmt);
listeners.prepared(context);
listeners.preExecute(context);
final ResultSet rs = stmt.executeQuery();
listeners.executed(context);
//... 생략
} finally {
stmt.close();
}
//... 생략
S Q L Q u e r y F a c t o r y 를 이용하는 경우 내부적으로
Q u e r y d s l 은 J D B C 기술을 사용한다는 것을 알 수
있습니다.