임대일

JPQL, Spring Data JPA, QueryDSL: 데이터베이스 CRUD 고르기 본문

스프링/지식

JPQL, Spring Data JPA, QueryDSL: 데이터베이스 CRUD 고르기

limdae94 2024. 7. 5. 13:16

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();
 
 
 
삭제
Querydsl 의 delete 메서드를 사용하여 삭제 쿼리를 작성할 수 있습니다.
long deleteCount = queryFactory.delete(member)
                               .where(member.id.eq(1L))
                               .execute();
 
  • 조회: Querydsl 을 사용하면 복잡한 조회 쿼리를 간결하고 타입 안전하게 작성할 수 있어 매우 유용하다.
  • 삽입 / 업데이트 / 삭제: Spring Data JPA가 제공하는 기본 메서드를 사용하는 것이 더 직관적이고 간편하다. 복잡한 업데이트나 삭제 작업이 필요한 경우 QueryDSL을 사용할 수 있다.

복잡한 조회 작업에 QueryDSL을 주로 사용하고, 삽입 / 업데이트 / 삭제 작업에는 Spring Data JPA의 기본 메서드를 사용하는 것이 좋다. 이렇게 하면 코드의 가독성과 유지 보수성을 높일 수 있다.