임대일
JPQL, Spring Data JPA, QueryDSL: 데이터베이스 CRUD 고르기 본문
1. JPQL
JPQL(Java Persistence Query Language)은 JPA에서 사용하는 객체 지향 쿼리 언어로, SQL과 유사하지만 엔티티 객체를 대상으로 쿼리를 작성한다.
JPQL 특징
- SQL과 유사하지만, 데이터베이스 테이블이 아니라 엔티티 객체를 대상으로 쿼리 수행
- JPQL 을 사용하면 엔티티 객체의 속성, 관계 등을 이용하여 복잡한 쿼리를 작성이 가능
- JPQL 은 EntityManager 를 사용하여 실행
- 예: SELECT m FROM Member m WHERE m.name = :name
String jpql = "SELECT m FROM Member m WHERE m.name = :name";
List<Member> members = entityManager.createQuery(jpql, Member.class)
.setParameter("name", "John")
.getResultList();
2. Spring Data JPA
Spring Data JPA는 Spring Framework 의 하위 프로젝트로, JPA 를 더 쉽게 사용할 수 있도록 도와주는 추상화된 레이어이다. 주로 리포지토리 패턴을 사용하여 데이터 액세스 계층을 간단히 구현할 수 있다.
Spring Data JPA 특징
- 리포지토리 인터페이스를 통해 기본적인 CRUD 및 커스텀 쿼리 메서드를 자동으로 생성한다.
- JPQL뿐만 아니라 네이티브 SQL 쿼리, QueryDSL 등 다양한 방식으로 쿼리를 작성할 수 있다,
- JpaRepository, CrudRepository 등의 인터페이스를 제공하여 데이터 접근을 쉽게 처리할 수 있다.
- 쿼리 메서드 이름을 통해 자동으로 쿼리를 생성한다.
- 예: List<Member> findByName(String name);
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByName(String name);
}
3. JPQL, JPA 비교
1. 쿼리 작성
- JPQL: 직접 쿼리 문자열을 작성하여 엔티티를 조회, 삽입, 수정, 삭제하는 쿼리를 작성한다.
- Spring Data JPA: 리포지토리 인터페이스와 메서드 이름으로 쿼리를 자동 생성하거나 JPQL, 네이티브 쿼리, QueryDSL 등을 사용할 수 있다.
2. 추상화 수준
- JPQL: 낮은 수준의 추상화로, 쿼리를 작성할 때 많은 세부 사항을 직접 관리해야 한다.
- Spring Data JPA: 높은 수준의 추상화로, 인터페이스와 메서드 이름을 통해 많은 작업이 자동으로 처리된다.
3. 유연성
- JPQL: 더 복잡하고 유연한 쿼리를 작성할 수 있지만, 코드가 더 복잡해질 수 있다.
- Spring Data JPA: 코드가 간결하고 유지 보수가 쉬워지지만, 매우 복잡한 쿼리는 직접 작성해야 할 수도 있다.
JPQL 과 Spring Data JPA 는 서로 보완적인 관계로, Spring Data JPA 는 JPQL 을 내부적으로 사용하지만, 더 높은 수준의 추상화를 제공하여 개발자의 편의성을 높인다.
4. Querydsl
하이버네이트 쿼리 언어(HQL: Hibernate Query Language)의 쿼리를 타입에 안전하게 생성 및 관리해주는 프레임워크이다. Querydsl 은 정적 타입을 이용하여 SQL 과 같은 쿼리를 생성할 수 있다. Querydsl 은 주로 조회 작업에서 많이 사용되지만, 삽입, 업데이트, 삭제 작업에서도 사용할 수 있다. JPQL, Spring Data JPA 는 복잡한 쿼리, 동적 쿼리를 구현하는 데 있어 오류 체킹, 코드 작성 등의 한계가 있다. 이러한 문제점을 해결할 수 있는 것이 Querydsl 이다. 일반적으로 복잡한 조회 쿼리를 작성할 때 QueryDSL을 사용하는 것이 더 효과적이다.
Querydsl 이 등장하기 이전에는 Mybatis, JPQL, Criteria 등 문자열 형태로 쿼리문을 작성하여 컴파일 시에 오류를 발견하는 것이 불가능했다. 하지만, Querydsl 은 자바 코드로 SQL 문을 작성할 수 있어 컴파일 시에 오류를 발생하여 잘못된 쿼리가 실행되는 것을 방지할 수 있다.
Querydsl 특징
- 문자가 아닌 코드로 쿼리를 작성할 수 있어 컴파일 시점에 문법 오류를 확인할 수 있다. (타입 안정성 보장)
- 인텔리제이와 같은 IDE의 자동 완성 기능의 도움을 받을 수 있다. (코드 자동 완성)
- 복잡한 쿼리나 동적 쿼리 작성이 편리하다.
- 쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용할 수 있다.
- JPQL 문법과 유사한 형태로 작성할 수 있어 쉽게 적응할 수 있다.
List<Member> findMembers(String name, Integer age) {
BooleanBuilder builder = new BooleanBuilder();
QMember member = QMember.member;
if (name != null) {
builder.and(member.name.eq(name));
}
if (age != null) {
builder.and(member.age.eq(age));
}
return queryFactory.selectFrom(member)
.where(builder)
.fetch();
}
Querydsl을 사용한 삽입, 업데이트, 삭제 작업
Querydsl 은 JPAQueryFactory 와 함께 사용되어 삽입, 업데이트, 삭제 작업도 가능하다. 그러나, 일반적으로 Spring Data JPA 가 제공하는 save(), delete() 메서드를 사용하는 것이 더 직관적이고 간단하다.
삽입
Querydsl 자체로는 삽입 작업을 직접 수행하지 않으며, JPA 의 EntityManager 를 사용하여 삽입 작업을 수행한다.
업데이트
Querydsl 의 update 메서드를 사용하여 업데이트 쿼리를 작성할 수 있다.
long updateCount = queryFactory.update(member)
.set(member.name, "newName")
.where(member.id.eq(1L))
.execute();
long deleteCount = queryFactory.delete(member)
.where(member.id.eq(1L))
.execute();
- 조회: Querydsl 을 사용하면 복잡한 조회 쿼리를 간결하고 타입 안전하게 작성할 수 있어 매우 유용하다.
- 삽입 / 업데이트 / 삭제: Spring Data JPA가 제공하는 기본 메서드를 사용하는 것이 더 직관적이고 간편하다. 복잡한 업데이트나 삭제 작업이 필요한 경우 QueryDSL을 사용할 수 있다.
복잡한 조회 작업에 QueryDSL을 주로 사용하고, 삽입 / 업데이트 / 삭제 작업에는 Spring Data JPA의 기본 메서드를 사용하는 것이 좋다. 이렇게 하면 코드의 가독성과 유지 보수성을 높일 수 있다.