1. JPQL
1-1) JPQL이란?
JPQL은 JPA에서 제공하는 객체지향 쿼리 언어 중 하나다.
JPQL은 엔티티 객체를 대상으로 쿼리를 작성할 수 있게 해준다.
1-2) JPQL의 특징
✔️ 객체지향 쿼리
- 관계형 데이터베이스의 테이블이 아닌 엔티티 객체를 대상으로 쿼리를 작성할 수 있다.
- 테이블과 컬럼 대신 엔티티 클래스와 필드를 참조한다.
✔️ 데이터베이스 독립성
- 특정 데이터베이스에 종속되지 않고 독립적인 쿼리를 작성할 수 있다. -> JPQL은 SQL로 변환된다.
- JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.
✔️ 표준화
- JPQL은 JPA 표준에 포함되어 있어서 다양한 JPA 구현체(Hibernate 등)에서 동일하게 사용할 수 있다.
1-3) JPQL의 한계점
- 특정 데이터베이스의 고유 기능이나 고급 SQL 기능은 JPQL에서 사용할 수 없다.
- 복잡한 조인, 서브쿼리 등을 다루기 어려울 수 있다.
- 문자열로 쿼리를 작성하다보니 동적 쿼리를 생성하기가 어렵고 컴파일 시점에서 오류를 잡을 수 없다.(오타, 잘못된 필드명 체크가 안됨)
- 데이터베이스 최적화를 직접적으로 제어하기 어렵다.
- 대량의 데이터를 수정하거나 삭제할 때 제약이 있을 수 있다.
💡이런 한계점을 마주할 땐! Native SQL 또는 JDBC를 직접 사용하면 된다. 상황에 맞는 적절한 쿼리 언어를 선택하자.
2. Criteria
2-1) Criteria 란?
JPA에서 엔티티 객체를 대상으로 타입 안전한 쿼리를 동적으로 작성할 수 있게 해주는 객체 지향 쿼리 API다.
💡Criteria 대신에 QueryDSL 사용하는게 낫다.
(그치만! Criteria가 뭔지는 알아보자. 그래야 다른 것들을 왜 사용해야하는 지 알게되니까)
2-2) Criteria의 특징
✔️ 타입 안정성
- JPQL과 유사하게 엔티티 객체를 대상으로 쿼리를 작성하지만, 쿼리 문자열을 사용하지 않고 메서드 호출을 통해 쿼리를 구성한다.
- 컴파일 시점에 쿼리의 문법과 타입을 체크할 수 있다.
✔️동적 쿼리
- 런타임에 조건에 따라 쿼리를 동적으로 생성할 수 있다.
(*쿼리 동적 생성 : 쿼리 작성 시 고정된 쿼리 문자열을 사용하는 대신에 조건이나 값을 동적으로 변경할 수 있다.)
✔️객체 지향적
- 쿼리를 객체 지향적으로 작성할 수 있다.
2-3) Criteria의 한계점
- 너무 복잡하고 실용성이 없다.
- 구문이 복잡해지면 쿼리 가독성이 떨어질 수 있다.
- 유지보수, 운영이 어려워서 실무에서는 거의 안쓴다.
3.QueryDSL
3-1) QueryDSL 이란?
타입 안전한 동적 쿼리를 작성할 수 있는 자바 라이브러리로, JPA뿐만 아니라 MongoDB, Elasticsearch 등 다양한 데이터 저장소와 통합될 수 있다. 실무에서 사용하길 권장하는 객체지향 쿼리 언어다.
3-2) QueryDSL의 특징
✔️타입 안정성
- 컴파일 시점에 쿼리의 문법과 데이터 타입을 체크할 수 있어서 런타임 오류를 줄일 수 있다
✔️가독성
- 쿼리 문자열을 사용하지 않고 메서드 체인을 사용하여 쿼리를 작성하니 코드의 가독성이 높다.
✔️통합성
- JPA뿐 아니라 다양한 데이터 저장소와 통합해서 사용할 수 있다.
✔️ 자동 코드 생성
- 도메인 모델을 기반으로 쿼리 타입을 자동 생성해준다.
(*도메인 모델 : 시스템의 비즈니스 로직과 규칙을 표현하는 개념적 모델, 객체지향 프로그래밍에서 주로 클래스와 객체로 구현됨.)
✔️동적 쿼리 작성
- 복잡한 조건을 동적으로 조합하여 쿼리를 작성할 수 있다.
✔️직관적 API
- 쿼리 작성을 위한 직관적인 API를 제공한다.
- 문법과 사용법을 익혀야하지만 Criteria보다 단순하고 쉽다.
💡 JPQL이 근본이 되기때문에 QueryDSL을 공부하기 전에 JPQL을 먼저 공부하는 것이 중요하다.
3-3) QueryDSL의 한계점
- 초기 설정이 다소 복잡하다.
- 복잡한 쿼리를 작성할 때, 가독성이 떨어질 수 있다. 쿼리 조건이 많거나 복잡한 조인이 포함된 경우 그렇다.
이럴땐, 빌더 패턴으로 캡슐화해서 가독성을 높일 수 있다.
- SQL의 모든 기능을 지원하지는 않아서 필요한 경우, Native SQL을 사용하면 된다.
여기부터 소개되는 것들은 객체지향 쿼리 언어가 아니다.
JPQL, QueryDSL을 쓰다가 해결이 안되는 문제가 있을 때, SQL을 직접 작성하고 실행하는 절차적 쿼리 방식이다.
4. Native SQL
- JPA가 제공하는 SQL을 직접 사용하는 기능이다.
- 특정 데이터베이스에 의존적인 기능을 사용할 때 쓴다. (JPQL로 해결할 수 없는 문제)
- SQL쿼리를 문자열로 작성하기때문에 컴파일 시점에서 타입 오류를 잡을 수 없다.
- 재사용성과 유지보수성이 떨어진다.
5. JDBC 직접사용(SpringJdbcTemplate 등)
- JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, SpringJdbcTemplate, MyBatis등을 함께 사용 가능하다.
- 영속성 컨텍스트를 적절한 시점에 강제로 플러시를 해야한다. (ex. SQL을 실행하기 직전 영속성 컨텍스트 flush)
6. 정리
실무에서는 주로 JPQL, QueryDSL로 웬만한 쿼리를 작성할 수 있다.
⭐객체지향 쿼리 언어를 처음 접한 다면, JPQL 사용법부터 익히는 것이다!
'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
JPA 기본 | JPQL 문법(2) - 프로젝션(SELECT) (0) | 2024.07.16 |
---|---|
JPA 기본 | JPQL 기본 문법(1) 쿼리 API, 파라미터 바인딩 (0) | 2024.07.15 |
JPA 기본 | 데이터 타입(3) - 값 타입 컬렉션 (0) | 2024.07.14 |
JPA 기본 | 데이터 타입(2) - 값 타입 공유와 불변객체 (0) | 2024.07.14 |
JPA 기본 | 데이터 타입(1) - 기본 값과 임베디드 값 타입 (0) | 2024.07.14 |