πβοΈ κ³μν΄μ μ λ°μ΄νΈ νκΈ° πβοΈ
λ§μ§λ§ μ λ°μ΄νΈ 2022/03/29
1. Querydsl μ μ μ¬μ©ν κΉ?
2. μλλ°©μ?
3. μμ‘΄μ±
4. Repository ꡬ쑰
5. Projection μ λν κ³ μ°° ...
6. λμ 쿼리 (BooleanBuilder)
7. ExpressionUtils
8. μ λ ¬ νμ μ λ°λ₯Έ μ λ ¬ μ²λ¦¬
Querydsl μ μ μ¬μ©ν κΉ?
JPA λ₯Ό μ¬μ©νλ©΄μ (@Query ν¬ν¨) μ‘°ν κΈ°λ₯μ λν νκ³κ° μλ€.
λμ μΈ μΏΌλ¦¬μΈ κ²½μ°μΈλ° μλ₯Ό λ€μ΄ μ£Όλ¬Έ νμ΄μ§λ₯Ό κ²μ νλ€κ³ νμ λ μΉ΄ν κ³ λ¦¬ or μνλͺ or κΈ°μ λͺ λ±λ±... μΌλ‘ κ²μ μ‘°κ±΄μ΄ λ¬λΌμ§λ λΆλΆμ΄λ€.
κ·Έλμ μ¬μ©νκ² λ κ²μ΄ λ°λ‘ Querydsl νλ μμν¬ μ΄λ€.
- νμ 체ν¬κ° λ°λ‘ κ°λ₯νλ€
- μλ° μ½λλ₯Ό κΈ°λ°μΌλ‘ 쿼리λ₯Ό μμ±νλ€
μλλ°©μ?
Querydsl -> JPQL -> SQL
μμ‘΄μ±
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</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>
μν°ν°λ₯Ό κΈ°λ°μΌλ‘ Q κ° λΆλ ν΄λμ€λ€μ μλ μμ±ν΄μ€λ€.
λΉλλ₯Ό ν΄λ³΄λ©΄ target/generated-sources/java μ¬κΈ°μ Qν΄λμ€λ€μ΄ μ겨λκ±Έ λ³Ό μ μλ€.
- querydsl-jpa : QueryDSL JPA λΌμ΄λΈλ¬λ¦¬
- querydsl-apt : 쿼리 νμ (Q)μ μμ±ν λ νμν λΌμ΄λΈλ¬λ¦¬
Repository ꡬ쑰
public interface UserRepository extends JpaRepository<Users, Long>, UserRepositoryCustom {
}
public interface UserRepositoryCustom {
List<Users> findByOrderByUser(Long userId, UserSearch userSearch);
}
public class UserRepositoryImpl extends QuerydslRepositorySupport implements
UserRepositoryCustom {
private JPAQueryFactory queryFactory;
// 1.
public UserRepositoryImpl() {
super(Users.class);
}
// 2.
@Override
public void setEntityManager(EntityManager entityManager) {
super.setEntityManager(entityManager);
queryFactory = new JPAQueryFactory(entityManager);
}
1. QuerydslRepositorySupportλ₯Ό μμνκ²λλ©΄ λ μ΄μ QueryDslμ μ¬μ©ν μ μμ΅λλ€.
λ¨, μμ±μμμ super(Entity.class)λ₯Ό νΈμΆνλ©΄ κ°λ₯ νλ€.
- QuerydslRepositorySupport ν΄λμ€μλ κΈ°λ³Έμμ±μκ° μμ.
2.
QuerydslRepositorySupport λ₯Ό μ¬μ©νλ©΄ ꡬν체μ JPQLQuery λ₯Ό μ¬μ©ν΄μ 쿼리λ₯Ό μ§νν΄μΌ νκΈ° λλ¬Έμ from μΌλ‘ μμν΄μΌ νλ€. κ·Έλμ queryFactory (μΌλ°μ μΌλ‘ μ¬μ©νλ select λ‘ μμνκΈ° μν΄ )λ₯Ό μ΄μ©νκΈ° μν΄
EntityManager λ₯Ό μμ ν΄λμ€μ μ λ¬νμ¬ JPAQueryμμ μ 곡ν΄μ£Όλ (select,selectFrom λ±λ± ..) μ ꡬνν μ μλ€.
-> μ±λ₯ μ°¨μ΄λ μμ§λ§ μΌλ°μ μΌλ‘ μ¬μ©νλ SQLλ‘ κ΅¬νν΄μ μ½λ κ°λ μ±μ λμ΄λ κ² λν μ΄λμ΄λΌκ³ μκ°νλ€!
Projection μ λν κ³ μ°° ...
쿼리λ₯Ό μ¬μ©νμ¬ νλμ νλλ₯Ό μ‘°ν νλ κ²μ μ½λ€.
List<String> result = queryFactory
.select(users.name)
.from(users)
.fetch();
νμ§λ§ λ³΄ν΅ μ¬λ¬ 리ν΄κ°μ΄ νμνλ° μλμ κ°μ΄ μμ±νλ€λ©΄ Tuple λ‘ λ°νλλ€.
μ°λ¦¬λ κ²°κ³Ό κ°μ κ°μ²΄λ‘ λ§λ€μ΄ μ¬μ©ν΄μΌ νκΈ° λλ¬Έμ DTO λ‘ λ§λ€μ΄ μ°λ λ°©λ²μ λν΄ μμλ³΄κ³ μ νλ€!
List<Tuple> result = queryFactory
.select(users.name,user.age)
.from(users)
.fetch();
Projections μ μ¬μ©νλ©΄ λλ€.
1. constructor
μμ±μ κΈ°λ° μμ±
-> λΆλ³ κ°μ²΄ μ΄μ§λ§ dto μμ±μμ νλΌλ―Έν° μμμ λμΌν΄μΌ νλ€.(νλκ° λ§μμλ‘ μ€μ μνμ΄ μλ€.)
-> μ΄λ¦μ λ§μΆ°μ£Όμ§ μμλ ν΄λΉμ리μ λ€μ΄κ°λ κ°μ λ£μ΄μ€λ€
List<UserInfoDto> result = queryFactory
.select(
Projections.constructor(UserInfoDto.class,
users.name,
user.age
))
.from(users)
.fetch();
2. bean
DTOμ μλ setter λ©μλ(@Setter) κΈ°λ° μμ±
-> DTOκ° λΆλ³ κ°μ²΄κ° μλκ² λκΈ° λλ¬Έμ μ§μνλ λ°©λ²
List<UserInfoDto> result = queryFactory
.select(
Projections.bean(UserInfoDto.class,
users.name.as("userName"),
user.age.as("userAge")
))
.from(users)
.fetch();
3. Fields
νλμ μ§μ μ κ·Όν΄μ κ°μ μ±μμ€λ€.
-> νλμ μ§μ μ κ·ΌνκΈ° λλ¬Έμ μ΄λ¦μ΄ ν리면 μλλ€
-> DB μ»¬λΌ μ΄λ¦κ³Ό DTO νλ μ΄λ¦μ΄ λ€λ₯Ό κ²½μ° .as λ‘ λ³κ²½νμ¬ λ£μ΄μ£Όλ©΄ λλ€
List<UserInfoDto> result = queryFactory
.select(
Projections.fields(UserInfoDto.class,
users.name.as("userName"),
user.age.as("userAge")
))
.from(users)
.fetch();
4. @QueryProjection
DTO μ λν Q class κΈ°λ° μμ±
-> DTO μμ±μμ @QueryProjection μ΄λ Έν μ΄μ μ μ μΈνκ³ querydsl λ₯Ό μ»΄νμΌ νλ©΄ QUserInfoDto.class μ²λΌ Q ν΄λμ€κ° μμ±λλ€.
-> Q ν΄λμ€ μμ±μ 미리 ν΄μΌ νλ€.
-> DTO κ° querydsl μ μμ‘΄νλ€λ λ¨μ μ΄ μλ€.
List<UserInfoDto> result = queryFactory
.select(
new QUserInfoDto(
users.name.as("userName"),
user.age.as("userAge")
))
.from(users)
.fetch();
λλ νλλ₯Ό μ£Όλ‘ μ¬μ©ν κ² κ°λ€.
1. μμ±μ - μ€λ¬΄μμλ μ λ μ¬μ© λͺ»ν κ² κ°λ€ dto νλκ° 10κ° μ΄μ μΌ λκ° λ§λ€
2. setter - λΆλ³μ± κ°μ²΄κ° μλλ λΆμνλ€
3. QueryProjection - Qν΄λμ€κ° μΆκ°λλ€λκ² λ§μ μλ€κ³ querydsl μ μμ‘΄μ΄ κ°ν΄μ§κΈ° λλ¬Έμ μ μ§λ³΄μμμ λ¬Έμ κ° λ°μν μ μμ κ² κ°λ€.
λμ 쿼리 (BooleanBuilder)
κ²μ λ±μμ μ¬μ©λ μ μλλ‘ μΏΌλ¦¬λ¬Έμ μμ±λλ 쑰건λ€μ nullable νκ² λ£μ΄μ€ μ μκ² ν΄μ€λ€.
1. μ μ λ₯Ό κ²μν λ μ΄λ¦μ΄λ λμ΄λ‘ κ²μνκ³ μΆλ€
2. μ΄λ¦νλλ‘ κ°μ λ°μ κ²½μ° builder.and(users.name.eq(name)) μΏΌλ¦¬κ° μλνλ€.
BooleanBuilder builder = new BooleanBuilder();
if (name != null) {
builder.and(users.name.eq(name));
}
if (age != null) {
builder.and(users.age.eq(age));
}
return jpaQueryFactory
.selectFrom(users)
.where(builder)
.fetch();
μ€λ¬΄μμλ μ’λ κ°λ μ±μ μ’κ² νκΈ° μν΄ μλμ κ°μ΄ μλλ€
return jpaQueryFactory
.selectFrom(users)
.where(eqName(name), eqAge(age))
.fetch();
}
private BooleanExpression eqName(String name) {
return name != null ? users.name.eq(name) : null;
}
private BooleanExpression eqAge(int age) {
return age == null ? users.age.eq(age) : null;
}
ExpressionUtils
http://querydsl.com/static/querydsl/4.4.0/apidocs/com/querydsl/core/types/ExpressionUtils.html
ExpressionUtils (Querydsl 4.4.0 API)
Converts the given object to an Expression Casts expressions and wraps everything else into co
querydsl.com
곡μ λ¬Έμμ 보면 μ΄λ€ λ©μλκ° μλμ§ νμΈν μ μλ€!
νμ¬μμ λ κ±°μ νλ‘μ νΈ μμ νλ κ²μ λ΄€λλ° ExpressionUtils λ‘ Subquery λ₯Ό ꡬννλκ±Έ λ³΄κ³ μ 리ν©λλ€!
νμ¬ νλ‘μ νΈμμλ μν°ν°λ‘ ꡬμ±λμ΄μκΈ° λλ¬Έμ μλΈμΏΌλ¦¬κ° νμν μΌμ κ±°μ μμλ€!
return jpaQueryFactory
.select(Projections.fields(
ExpressionUtils.as(getUserCount(UserStatus.νν΄νμ),"usersCount"))
.from(users).fetchCount());
private JPQLQuery<Long> getUserCount(UserStatus status){
return select(users.id.count())
.from(users)
.where(status == null ? null : eqUserStatus(status))
}
private Predicate eqUserStatus(UserStatus status){
return users.status.eq(status);
}
μ¬κΈ°μ as λ‘ μ리μμ€λ₯Ό ν΄μ£Όλλ° νλΌλ―Έν°λ‘ λ°λ Expression μ μλμ κ°μ νμ μ λ°μ μ μλ€. κ·Έλμ JPQLQuery λ₯Ό λ§λ€μ΄μ νλΌλ―Έν°λ‘ λμ ν΄μ£Όμλ€!
Predicate λ μλ°μ½λλ‘ μ‘°κ±΄λ¬Έμ νν(where μ )ν μ μκ² ν΄μ£Όμ΄μ 쑰건문λ€μ λ°λ‘ κ΄λ¦¬ν μ μλλ‘ ν΄μ€λλ€~!
http://querydsl.com/static/querydsl/4.4.0/apidocs/com/querydsl/core/types/Expression.html
Expression (Querydsl 4.4.0 API)
Expression defines a general typed expression in a Query instance. The generic type parameter is a reference to the type the expression is bound to. The central Expression subinterfaces are
querydsl.com
μ λ ¬ νμ μ λ°λ₯Έ μ λ ¬ μ²λ¦¬
private OrderSpecifier getOrderBy(Order sortType) {
switch (sortType) {
case μ΅κ·Όκ°μ
:
return new OrderSpecifier(Order.DESC, user.createAt);
case λμμ°λ Ήμ:
return new OrderSpecifier(Order.ASC, user.age);
case νμμν:
return new OrderSpecifier(Order.ASC, user.status);
default:
return new OrderSpecifier(Order.ASC, user.createAt);
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.querydsl.core.types;
public enum Order {
ASC,
DESC;
private Order() {
}
}
'WEB > JPA' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Querydsl] λ΄κ° μ°Ύμ μ°λ €κ³ μ 리ν κΈ (0) | 2022.03.15 |
---|---|
7. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - νλ‘μμ μ°κ΄κ΄κ³ κ΄λ¦¬ (0) | 2021.05.18 |
6. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - κ³ κΈλ§€ν (0) | 2021.05.17 |
5. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - λ€μν μ°κ΄κ΄κ³ λ§€ν (0) | 2021.05.14 |
4. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - μ°κ΄κ΄κ³ (0) | 2021.05.14 |
3. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - μν°ν° λ§€ν (0) | 2021.05.13 |
WEB/JPA μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
7. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - νλ‘μμ μ°κ΄κ΄κ³ κ΄λ¦¬
6. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - κ³ κΈλ§€ν
5. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - λ€μν μ°κ΄κ΄κ³ λ§€ν
4. μλ° ORM νμ€ JPA νλ‘κ·Έλλ° - μ°κ΄κ΄κ³