Querydsl
Querydsl์ ํ์
์์ ํ SQL ๋ฐ JPQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ์ ์๋๋ก ๋์์ฃผ๋ ํ๋ ์์ํฌ์
๋๋ค.
Querydsl ์ ์
Querydsl์ SQL, JPQL, JPA๋ฅผ ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์๋๋ก ์ง์ํ๋ ํ์
์์ ํ ์ฟผ๋ฆฌ ๋น๋ API์
๋๋ค.
๋์ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ๊ฒฐํ ์ฝ๋๋ก ์์ฑํ ์ ์์ผ๋ฉฐ, ์ปดํ์ผ ์์ ์์ ์ค๋ฅ๋ฅผ ๊ฒ์ถํ ์ ์์ต๋๋ค.
โข
SQL, JPQL, JPA, MongoDB ๋ฑ ๋ค์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํธํ
โข
์ฝ๋ ์๋ ์์ฑ(Q-Class)์ผ๋ก ์ง๊ด์ ์ธ ๋ฉ์๋ ์ฒด์ด๋ ์ง์
โข
๋ฉ์๋ ์ฒด์ด๋ ๋ฐฉ์์ผ๋ก ๊ฐ๋
์ฑ์ด ๋ฐ์ด๋จ
โข
JPQL๊ณผ ๋์ผํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉด์๋ ๋ ๊ฐ๊ฒฐํ ์ฝ๋ ์์ฑ ๊ฐ๋ฅ
โข
์ปดํ์ผ ํ์ ํ์
์ฒดํฌ ์ง์ โ ์ค๋ฅ๋ฅผ ์ฌ์ ์ ๋ฐฉ์ง
Querydsl ์ฃผ์ ์ด๋
ธํ
์ด์
๋ฐ ํด๋์ค
ํด๋์ค | ์ค๋ช
|
JPAQueryFactory | Querydsl์ ์ฟผ๋ฆฌ ๋น๋ ๊ฐ์ฒด (์ฟผ๋ฆฌ ์คํ์ ์ํ ์ค์ฌ ํด๋์ค) |
QEntity | Querydsl์ด ์๋ ์์ฑํ ์ํฐํฐ ํด๋์ค (์: QUsers, QBoards) |
BooleanExpression | where() ์กฐ๊ฑด์ ๋์ ์ผ๋ก ์ถ๊ฐํ ๋ ์ฌ์ฉ |
Projections | DTO ๋งคํ ์ ์ฌ์ฉ |
Expressions | ๋ณต์กํ ์ฐ์ฐ์ ์ํํ ๋ ์ฌ์ฉ |
Querydsl ์ค์ ๋ฐ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
Querydsl ์ค์ (Spring Boot ๊ธฐ์ค)
1. Gradle ์์กด์ฑ ์ถ๊ฐ
dependencies {
implementation 'com.querydsl:querydsl-jpa:5.0.0'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'
}
Plain Text
๋ณต์ฌ
2. QClass ์๋ ์์ฑ ํ๋ฌ๊ทธ์ธ ์ถ๊ฐ
tasks.withType(JavaCompile).configureEach {
options.annotationProcessorGeneratedSourcesDirectory = file("$buildDir/generated")
}
Plain Text
๋ณต์ฌ
3. QClass ๋น๋ (์๋ ์์ฑ)
./gradlew clean compileJava
Plain Text
๋ณต์ฌ
Querydsl ํต์ฌ ์ฌ์ฉ๋ฒ
JPAQueryFactory ์ค์
@RequiredArgsConstructor
@Repository
public class UserRepository {
private final JPAQueryFactory queryFactory;
}
Java
๋ณต์ฌ
์ ์ฒด ์กฐํ (SELECT)
public List<Users> findAllUsers() {
QUsers users = QUsers.users; // Querydsl์ด ์๋ ์์ฑํ QClass
return queryFactory
.selectFrom(users)
.fetch();
}
Java
๋ณต์ฌ
์กฐ๊ฑด ๊ฒ์ (WHERE)
public Users findByUsername(String username) {
QUsers users = QUsers.users;
return queryFactory
.selectFrom(users)
.where(users.username.eq(username))
.fetchOne();
}
Java
๋ณต์ฌ
์ฌ๋ฌ ์กฐ๊ฑด ๋์ ๊ฒ์ (BooleanExpression ํ์ฉ)
public List<Users> findUsers(String username, Integer age) {
QUsers users = QUsers.users;
return queryFactory
.selectFrom(users)
.where(eqUsername(username), eqAge(age))
.fetch();
}
private BooleanExpression eqUsername(String username) {
return username != null ? QUsers.users.username.eq(username) : null;
}
private BooleanExpression eqAge(Integer age) {
return age != null ? QUsers.users.age.eq(age) : null;
}
Java
๋ณต์ฌ
์ ๋ ฌ (ORDER BY)
public List<Users> findUsersSortedByAge() {
QUsers users = QUsers.users;
return queryFactory
.selectFrom(users)
.orderBy(users.age.desc()) // ๋์ด ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ
.fetch();
}
Java
๋ณต์ฌ
ํ์ด์ง (LIMIT & OFFSET)
public List<Users> findUsersWithPaging(int offset, int limit) {
QUsers users = QUsers.users;
return queryFactory
.selectFrom(users)
.orderBy(users.id.asc())
.offset(offset)
.limit(limit)
.fetch();
}
Java
๋ณต์ฌ
JOIN ํ์ฉ
public List<Boards> findBoardsWithUser(Long userId) {
QBoards boards = QBoards.boards;
QUsers users = QUsers.users;
return queryFactory
.selectFrom(boards)
.join(boards.user, users) // Boards โ Users JOIN
.where(users.id.eq(userId))
.fetch();
}
Java
๋ณต์ฌ
DTO ๋งคํ (Projections ํ์ฉ)
public List<UserDTO> findUsersAsDTO() {
QUsers users = QUsers.users;
return queryFactory
.select(Projections.constructor(UserDTO.class, users.id, users.username, users.age))
.from(users)
.fetch();
}
Java
๋ณต์ฌ
Querydsl vs JPQL vs Criteria API ๋น๊ต
๋น๊ต ํญ๋ชฉ | Querydsl | JPQL | Criteria API |
ํ์
์์ ์ฑ | |||
๊ฐ๋
์ฑ | |||
๋์ ์ฟผ๋ฆฌ ์ง์ | |||
ํ์ด์ง ์ง์ | |||
JOIN ์ฒ๋ฆฌ |
Querydsl ์์ฝ
1.
ํ์
์์ ํ ๋์ ์ฟผ๋ฆฌ ์์ฑ ๊ฐ๋ฅ
2.
JPQL๋ณด๋ค ๊ฐ๊ฒฐํ๊ณ ์ ์ง๋ณด์์ฑ์ด ๋ฐ์ด๋จ
3.
๋ฉ์๋ ์ฒด์ด๋ ๋ฐฉ์์ผ๋ก ๊ฐ๋
์ฑ์ด ๋์
4.
QClass ์๋ ์์ฑ์ผ๋ก ๊ฐ๋ฐ ํธ์์ฑ ์ฆ๊ฐ
5.
ํ์ด์ง, JOIN, DTO ๋ณํ์ ์ฝ๊ฒ ์ฒ๋ฆฌ ๊ฐ๋ฅ