Spring/Spring JPA
JPQL 간단히
개발자잡
2025. 1. 6. 22:11
JPQL(Java Persistence Query Language)은 JPA(Java Persistence API)에서 제공하는 객체지향 쿼리 언어입니다. SQL과 유사하지만, 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 동작한다는 점에서 차이가 있습니다. JPQL은 데이터베이스 독립적으로 작동하며, 애플리케이션 코드 내에서 사용됩니다.
JPQL의 주요 특징
- 객체 지향적 접근
- SQL은 데이터베이스의 테이블, 컬럼을 직접 다루는 반면, JPQL은 엔티티와 그 필드를 기반으로 작성됩니다.
- 예를 들어, SQL에서 SELECT * FROM user는 JPQL에서 SELECT u FROM User u와 같습니다.
- JPA 엔티티 매핑
- JPQL은 엔티티 클래스와 필드 이름을 사용합니다. 따라서 JPA 매핑이 제대로 되어 있어야 올바르게 작동합니다.
- 데이터베이스 독립적
- JPQL은 특정 데이터베이스에 의존하지 않으므로, 데이터베이스가 변경되어도 동일한 JPQL을 사용할 수 있습니다.
- SQL과 유사한 문법
- JPQL의 문법은 SQL과 비슷하지만, GROUP BY, ORDER BY, JOIN 등의 구문도 객체 관점에서 동작합니다.
JPQL 기본 구문
1. SELECT 문
- 데이터를 조회할 때 사용합니다.
SELECT u FROM User u WHERE u.name = 'John'
여기서 User는 엔티티 클래스이고, u는 별칭(alias)입니다.
2. WHERE 조건절
- 특정 조건에 따라 데이터를 필터링합니다.
SELECT u FROM User u WHERE u.age > 20
3. ORDER BY 절
- 데이터를 정렬합니다.
SELECT u FROM User u ORDER BY u.name ASC
4. JOIN 문
- 연관 관계가 설정된 엔티티를 조인합니다.
SELECT o FROM Order o JOIN o.customer c WHERE c.name = 'John'
5. GROUP BY 및 HAVING
- 데이터를 그룹화하고 특정 조건으로 필터링합니다.
SELECT c.name, COUNT(o) FROM Customer c JOIN c.orders o GROUP BY c.name HAVING COUNT(o) > 2
6. UPDATE 및 DELETE
- JPQL에서도 데이터 수정 및 삭제가 가능합니다.
// Update
UPDATE User u SET u.status = 'INACTIVE' WHERE u.lastLogin < :lastYear
// Delete
DELETE FROM User u WHERE u.status = 'INACTIVE'
JPQL과 SQL의 차이
특징 | JPQL | SQL |
대상 | 엔티티와 엔티티 필드 | 데이터베이스 테이블과 컬럼 |
문법 | 객체 지향적 (엔티티 기반) | 절차적 (테이블 기반) |
데이터베이스 의존성 | 데이터베이스 독립적 | 데이터베이스에 종속적 |
연관 관계 처리 | 엔티티의 연관 관계 매핑을 사용하여 자동으로 처리 가능 | JOIN을 사용하여 직접 처리 |
JPQL의 예제
1. 간단한 조회
@Query("SELECT u FROM User u WHERE u.age > :age")
List<User> findUsersOlderThan(@Param("age") int age);
2. JOIN과 조건 사용
@Query("SELECT o FROM Order o JOIN o.customer c WHERE c.name = :name")
List<Order> findOrdersByCustomerName(@Param("name") String name);
3. Aggregation 함수와 GROUP BY
@Query("SELECT c.name, COUNT(o) FROM Customer c JOIN c.orders o GROUP BY c.name")
List<Object[]> countOrdersByCustomer();
4. UPDATE 쿼리
@Modifying
@Query("UPDATE User u SET u.status = 'ACTIVE' WHERE u.lastLogin > :lastLogin")
int activateUsers(@Param("lastLogin") LocalDateTime lastLogin);
5. DELETE 쿼리
@Modifying
@Query("DELETE FROM User u WHERE u.status = 'INACTIVE'")
int deleteInactiveUsers();
JPQL을 사용할 때 주의할 점
- 필드 이름
- 엔티티의 필드 이름을 기준으로 작성해야 하며, 데이터베이스의 컬럼 이름을 직접 사용하지 않습니다.
- Lazy Loading 주의
- 연관된 엔티티를 조회할 때, 필요 이상의 데이터를 로드하지 않도록 Fetch 전략을 잘 설정해야 합니다.
- Native Query와 구분
- JPQL은 JPA의 관리 하에 작동하지만, 복잡한 쿼리에는 네이티브 SQL을 사용할 수도 있습니다.
JPQL은 JPA의 핵심 요소 중 하나로, 데이터베이스를 객체 지향적으로 다룰 수 있는 강력한 도구입니다. 주어진 엔티티 모델에 맞춰 작성하면 유지 보수성과 확장성을 모두 확보할 수 있습니다. 특히 프로젝트에서 도메인 모델과 데이터베이스 간의 간격을 줄이기 위해 필수적인 도구입니다.