1. Querydsl이란?
Querydsl은 Java 애플리케이션에서 타입 안전한 쿼리를 작성할 수 있도록 도와주는 라이브러리로, 기본적으로 Q 클래스를 통해 엔티티 클래스의 속성에 접근하여 동적 쿼리를 생성한다. Q 클래스는 컴파일 타임에 타입 안전성을 제공하며, 이를 통해 쿼리 빌더(JPAQuery, SQLQuery 등)를 사용해 조건에 맞는 쿼리를 동적으로 구성할 수 있다. 쿼리 실행 시, 데이터베이스에 맞게 변환된 쿼리가 실행되며, 결과는 fetch(), fetchOne(), fetchCount() 등의 메서드를 통해 반환된다. 이 방식은 SQL 문자열을 직접 작성하는 대신 Java 코드로 쿼리를 작성함으로써 가독성을 높이고 오류를 줄이며, 동적 쿼리 생성을 통해 복잡한 조건을 효율적으로 처리할 수 있게 해준다.
그리고 Querydsl에서는 INSERT 쿼리를 직접 지원하지 않는다. Querydsl은 주로 SELECT 쿼리와 관련된 동적 쿼리 생성에 초점을 맞춘 라이브러리이기 때문에, 데이터베이스에 INSERT 작업을 수행하는 데는 다른 방법을 사용해야 한다.
Q 클래스가 뭔데?
Q 클래스는 Querydsl에서 타입 안전한 쿼리를 작성할 수 있도록 도와주는 특별한 클래스이다. 각 엔티티 클래스에 대해 자동으로 생성되는 이 클래스는 해당 엔티티의 필드를 정적 변수 로 선언하여, 쿼리에서 해당 필드를 참조할 수 있게 한다. 예를 들어, Member 라는 엔티티 클래스가 있으면 Querydsl은 QMember
라는 클래스를 자동으로 생성한다. 이 클래스는 Member 엔티티의 각 속성(필드)에 대해 타입-safe하게 접근할 수 있도록 도와주며, 이를 통해 쿼리 작성 시 컴파일 타임에 오류를 잡을 수 있게 한다. Q 클래스는 또한 JPAQuery, SQLQuery와 같은 쿼리 빌더와 함께 사용되어 동적이고 복잡한 쿼리를 작성하는 데 유용하게 활용된다.
2. Querydsl의 내부 동작
2.1. 쿼리 타입 생성
Querydsl은 엔티티 클래스나 다른 도메인 객체를 기반으로 Q 클래스를 생성한다. 이 Q 클래스는 엔티티의 필드를 정적 변수로 선언한 클래스로, 각 필드를 쿼리할 수 있도록 도와준다. 예를 들어, Member라는 엔티티가 있을 경우, Querydsl은 QMember라는 클래스를 자동으로 생성하여 해당 엔티티의 속성들에 접근할 수 있게 한다.
Member.java
@Entity
public class Member {
@Id
private Long id;
private String name;
private int age;
// getter, setter, etc.
}
QMember.java
public class QMember extends EntityPathBase<Member> {
public static final QMember member = new QMember("member");
public final NumberPath<Long> id = createNumber("id", Long.class);
public final StringPath name = createString("name");
public final NumberPath<Integer> age = createNumber("age", Integer.class);
public QMember(String variable) {
super(Member.class, forVariable(variable));
}
}
2.2. 쿼리 빌딩
Querydsl에서는 JPAQuery, SQLQuery, MongoQuery 등과 같은 쿼리 객체를 사용하여 동적 쿼리를 빌드한다. 이 쿼리 객체는 Q 클래스에 정의된 필드를 활용하여 쿼리의 조건을 동적으로 설정할 수 있게 해줍니다. 쿼리 객체는 메서드 체이닝 방식을 통해 쿼리를 구성할 수 있다.
QMember member = QMember.member;
JPAQuery<Member> query = new JPAQuery<>(entityManager);
List<Member> members = query.select(member)
.from(member)
.where(member.age.gt(30))
.fetch();
위의 예시에서는 member.age.gt(30)라는 조건을 통해 30세 이상인 회원들을 조회하는 쿼리를 동적으로 생성한다.
2.3.쿼리 실행 (Query Execution)
쿼리 빌딩이 완료되면, fetch(), fetchOne(), fetchCount() 등의 메서드를 호출하여 실제로 쿼리가 실행됩니다. 이 과정에서 JPA, SQL, MongoDB 등 사용된 데이터베이스에 맞는 쿼리가 생성되어 실행된다.
- fetch(): 결과를 리스트로 반환한다.
- fetchOne(): 단일 결과를 반환한다.
- fetchCount(): 결과의 개수를 반환한다.
쿼리 실행은 실제로 JPAQuery나 SQLQuery 객체에서 해당하는 데이터베이스 쿼리를 실행하게 됩니다. 이 때, 생성된 쿼리는 데이터베이스에 맞게 적절하게 변환되어 실행된다.
쿼리 메소드들은 아래 문서에서 찾아볼 수 있다.
http://querydsl.com/static/querydsl/latest/reference/html/
Querydsl Reference Guide
This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the Apache License, Version 2.0.
querydsl.com
2.4. 컴파일 타임 타입 안전성
Querydsl의 중요한 특징 중 하나는 타입 안전성입니다. Q 클래스에서 제공하는 필드들은 모두 타입이 명확하게 정의되어 있기 때문에, 쿼리 작성 시 컴파일 타임에 오류를 체크할 수 있다. 예를 들어, member.age 필드에 잘못된 타입의 값을 넣으려 하면 컴파일 오류가 발생한다.
2.5. 동적 쿼리 지원
Querydsl은 조건에 따라 동적으로 쿼리를 수정할 수 있는 기능을 지원한다. 예를 들어, 사용자가 선택한 필터 조건에 따라 쿼리를 동적으로 구성할 수 있다.
BooleanBuilder builder = new BooleanBuilder();
if (name != null) {
builder.and(member.name.eq(name));
}
if (age != null) {
builder.and(member.age.gt(age));
}
List<Member> members = new JPAQuery<>(entityManager)
.select(member)
.from(member)
.where(builder)
.fetch();
2.6 결과 반환
쿼리 실행 후, fetch() 메서드를 사용하여 결과를 반환하면, Querydsl은 데이터베이스에서 반환된 레코드를 자바 객체로 매핑하여 반환 한다. 이 매핑 과정은 JPA의 EntityManager가 처리하게 되며, 결과는 List, Page, Optional 등의 형태로 반환될 수 있다.
'Spring' 카테고리의 다른 글
POSTMAN 테스트의 한계, SPRING TEST 도입(단위 테스트) (1) | 2025.02.07 |
---|---|
Spring Boot - ResponseEntity 클래스 (0) | 2025.01.11 |
Spring Boot - Lombok (0) | 2024.04.03 |
Spirng Boot - REST API로 CRUD 만들기 (0) | 2024.04.03 |
Spring Security 살펴보기 (0) | 2024.02.22 |
1. Querydsl이란?
Querydsl은 Java 애플리케이션에서 타입 안전한 쿼리를 작성할 수 있도록 도와주는 라이브러리로, 기본적으로 Q 클래스를 통해 엔티티 클래스의 속성에 접근하여 동적 쿼리를 생성한다. Q 클래스는 컴파일 타임에 타입 안전성을 제공하며, 이를 통해 쿼리 빌더(JPAQuery, SQLQuery 등)를 사용해 조건에 맞는 쿼리를 동적으로 구성할 수 있다. 쿼리 실행 시, 데이터베이스에 맞게 변환된 쿼리가 실행되며, 결과는 fetch(), fetchOne(), fetchCount() 등의 메서드를 통해 반환된다. 이 방식은 SQL 문자열을 직접 작성하는 대신 Java 코드로 쿼리를 작성함으로써 가독성을 높이고 오류를 줄이며, 동적 쿼리 생성을 통해 복잡한 조건을 효율적으로 처리할 수 있게 해준다.
그리고 Querydsl에서는 INSERT 쿼리를 직접 지원하지 않는다. Querydsl은 주로 SELECT 쿼리와 관련된 동적 쿼리 생성에 초점을 맞춘 라이브러리이기 때문에, 데이터베이스에 INSERT 작업을 수행하는 데는 다른 방법을 사용해야 한다.
Q 클래스가 뭔데?
Q 클래스는 Querydsl에서 타입 안전한 쿼리를 작성할 수 있도록 도와주는 특별한 클래스이다. 각 엔티티 클래스에 대해 자동으로 생성되는 이 클래스는 해당 엔티티의 필드를 정적 변수 로 선언하여, 쿼리에서 해당 필드를 참조할 수 있게 한다. 예를 들어, Member 라는 엔티티 클래스가 있으면 Querydsl은 QMember
라는 클래스를 자동으로 생성한다. 이 클래스는 Member 엔티티의 각 속성(필드)에 대해 타입-safe하게 접근할 수 있도록 도와주며, 이를 통해 쿼리 작성 시 컴파일 타임에 오류를 잡을 수 있게 한다. Q 클래스는 또한 JPAQuery, SQLQuery와 같은 쿼리 빌더와 함께 사용되어 동적이고 복잡한 쿼리를 작성하는 데 유용하게 활용된다.
2. Querydsl의 내부 동작
2.1. 쿼리 타입 생성
Querydsl은 엔티티 클래스나 다른 도메인 객체를 기반으로 Q 클래스를 생성한다. 이 Q 클래스는 엔티티의 필드를 정적 변수로 선언한 클래스로, 각 필드를 쿼리할 수 있도록 도와준다. 예를 들어, Member라는 엔티티가 있을 경우, Querydsl은 QMember라는 클래스를 자동으로 생성하여 해당 엔티티의 속성들에 접근할 수 있게 한다.
Member.java
@Entity
public class Member {
@Id
private Long id;
private String name;
private int age;
// getter, setter, etc.
}
QMember.java
public class QMember extends EntityPathBase<Member> {
public static final QMember member = new QMember("member");
public final NumberPath<Long> id = createNumber("id", Long.class);
public final StringPath name = createString("name");
public final NumberPath<Integer> age = createNumber("age", Integer.class);
public QMember(String variable) {
super(Member.class, forVariable(variable));
}
}
2.2. 쿼리 빌딩
Querydsl에서는 JPAQuery, SQLQuery, MongoQuery 등과 같은 쿼리 객체를 사용하여 동적 쿼리를 빌드한다. 이 쿼리 객체는 Q 클래스에 정의된 필드를 활용하여 쿼리의 조건을 동적으로 설정할 수 있게 해줍니다. 쿼리 객체는 메서드 체이닝 방식을 통해 쿼리를 구성할 수 있다.
QMember member = QMember.member;
JPAQuery<Member> query = new JPAQuery<>(entityManager);
List<Member> members = query.select(member)
.from(member)
.where(member.age.gt(30))
.fetch();
위의 예시에서는 member.age.gt(30)라는 조건을 통해 30세 이상인 회원들을 조회하는 쿼리를 동적으로 생성한다.
2.3.쿼리 실행 (Query Execution)
쿼리 빌딩이 완료되면, fetch(), fetchOne(), fetchCount() 등의 메서드를 호출하여 실제로 쿼리가 실행됩니다. 이 과정에서 JPA, SQL, MongoDB 등 사용된 데이터베이스에 맞는 쿼리가 생성되어 실행된다.
- fetch(): 결과를 리스트로 반환한다.
- fetchOne(): 단일 결과를 반환한다.
- fetchCount(): 결과의 개수를 반환한다.
쿼리 실행은 실제로 JPAQuery나 SQLQuery 객체에서 해당하는 데이터베이스 쿼리를 실행하게 됩니다. 이 때, 생성된 쿼리는 데이터베이스에 맞게 적절하게 변환되어 실행된다.
쿼리 메소드들은 아래 문서에서 찾아볼 수 있다.
http://querydsl.com/static/querydsl/latest/reference/html/
Querydsl Reference Guide
This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the Apache License, Version 2.0.
querydsl.com
2.4. 컴파일 타임 타입 안전성
Querydsl의 중요한 특징 중 하나는 타입 안전성입니다. Q 클래스에서 제공하는 필드들은 모두 타입이 명확하게 정의되어 있기 때문에, 쿼리 작성 시 컴파일 타임에 오류를 체크할 수 있다. 예를 들어, member.age 필드에 잘못된 타입의 값을 넣으려 하면 컴파일 오류가 발생한다.
2.5. 동적 쿼리 지원
Querydsl은 조건에 따라 동적으로 쿼리를 수정할 수 있는 기능을 지원한다. 예를 들어, 사용자가 선택한 필터 조건에 따라 쿼리를 동적으로 구성할 수 있다.
BooleanBuilder builder = new BooleanBuilder();
if (name != null) {
builder.and(member.name.eq(name));
}
if (age != null) {
builder.and(member.age.gt(age));
}
List<Member> members = new JPAQuery<>(entityManager)
.select(member)
.from(member)
.where(builder)
.fetch();
2.6 결과 반환
쿼리 실행 후, fetch() 메서드를 사용하여 결과를 반환하면, Querydsl은 데이터베이스에서 반환된 레코드를 자바 객체로 매핑하여 반환 한다. 이 매핑 과정은 JPA의 EntityManager가 처리하게 되며, 결과는 List, Page, Optional 등의 형태로 반환될 수 있다.
'Spring' 카테고리의 다른 글
POSTMAN 테스트의 한계, SPRING TEST 도입(단위 테스트) (1) | 2025.02.07 |
---|---|
Spring Boot - ResponseEntity 클래스 (0) | 2025.01.11 |
Spring Boot - Lombok (0) | 2024.04.03 |
Spirng Boot - REST API로 CRUD 만들기 (0) | 2024.04.03 |
Spring Security 살펴보기 (0) | 2024.02.22 |