-
-
안녕하세요? 오늘은, JPA의 쿼리 방법 중 하나인, JQPL에 대해 알아보도록 하겠습니다.
JPQL
(Java Persistence Query Language)
: 객체지향 쿼리 언어 : 테이블 대상이 아닌,엔티티를 대상으로 쿼리 : SQL을 추상화 > 특정 DB에 의존하지 않음 : JPQL은 결국 SQL로 변환 |
샘플 예시)
select 문 :: = select_절 from_절 [where_절] [groupby_절] [having_절] [orderby_절] update_문 :: = update_절 [where_절] delete_문 :: = delete_절 [where_절] |
사용법
: 엔티티와 속성은 대소문자 구분이 필수 : JPQL 키워드는 대소문자 구분 불필요 : 엔티티 이름 사용 > 테이블 이름 X : 별칭(Alias)은 필수 (as는 생략가능) : 집합과 정렬 등의 Ansi SQL 모두 사용 가능 (count, sum, avg, max, min) + 반환 타입이 명확할 때 : TypeQuery 사용 + 반환 타입이 미명확할 때 : Query 사용 |
TypedQuery<엔티티> query1 = em.createQuery("SELECT e FROM 엔티티 e", 엔티티.class);
Query query2 = em.createQuery("SELECT e.컬럼A, e.컬럼B FROM 엔티티 e");
// 반환 데이터가 다중건
List<엔티티> resultList1 = query1.getResultList();
List<엔티티> resultList2 = query2.getResultList();
// 반환 데이터가 단건
엔티티 result1 = query1.getSingleResult();
엔티티 result2 = query2.getSingleResult();
+
getResultList
: 결과가 하나 이상일 때 리스트 반환
> 없으면 빈 리스트 반환
+
getSingleResult
: 결과가 정확히 하나이고, 단일 객체 반환일 때 사용
> 결과가 없으면 NoResultException 발생
> 둘 이상이면 NonUniqueResultException 발생
-
데이터 바인딩
샘플 코드)
TypedQuery<엔티티> query1 = em.createQuery("SELECT e FROM 엔티티 e where e.컬럼A = :조건컬럼A", 엔티티.class);
query1.setParameter(조건컬럼A, 값);
// 반환 데이터가 다중건
List<엔티티> resultList1 = query1.getResultList();
// 반환 데이터가 단건
엔티티 result1 = query1.getSingleResult();
프로젝션
: 조회 절에 조회할 대상을 지정하는 것
: 엔티티, 임베디드 값타입, 스칼라 타입 대상
: DISTINCT로 중복 제거 가능
ex) SELECT e FROM 엔티티 e SELECT e.컬럼 FROM 엔티티 e SELECT e.임베디드컬럼 FROM 엔티티 e SELECT e.컬럼A, e.컬럼B FROM 엔티티 e |
++
예를 들어서, Member 엔티티와 Team 엔티티가 존재하고, 연관관계가 설정되어있다고 가정할 때, 조회 할 대상의 반환타입을 Team으로 지정
샘플 코드)
TypedQuery<Member> query = em.createQuery("SELECT m.team FROM Member m", Team.class);
List<엔티티> resultList = query.getResultList();
페이징
: JPA는 페이징을 두가지 API로 추상화
: 각 DB에 맞게끔 자동 페이징 쿼리 생성 조회
+
사용법
: setFirstResult(int startPosition)
> 조회 시작 위치
> 0부터 시작
: setMaxResult(int maxResult)
> 조회할 데이터 수
샘플코드)
String jqpl = "SELECT e FROM 엔티티 e";
List<엔티티> resultList = em.createQuery(jqpl, 엔티티.class)
.setFirstResult(1)
.setMaxResult(10)
getResultList();
System.out.println("resultList : " + resultList);
JOIN
(내부조인 / 외부조인 / 세타조인)
: 내부조인 > select e from 엔티티 e [INNER] join e.연관관계객체 s : 기본으로 key값 매핑이 되고, 추가 조건은 on을 쓴다. > select e from 엔티티 e [INNER] join e.연관관계객체 s on s.조건 : 외부조인 > select e from 엔티티 e left [OUTER] join e.연관관계객체 s : 기본으로 key값 매핑이 되고, 추가 조건은 on을 쓴다. >> select e from 엔티티 e [INNER] join e.연관관계객체 s on s.조건 : 세타조인 > select e, s from 엔티티 e, 조인엔티티 s where e.조건컬럼 = s.조건컬럼 |
+
Member엔티티와 Team엔티티가 서로, 연관관계가 셋팅되어있다고 가정하고, Team의 name컬럼에 '신'데이터가 포함 된 데이터를 조회
샘플코드)
// 내부 조인
String jqpl = "SELECT m FROM Member m INNER JOIN m.team t ON t.name = '%신%'";
List<Member> resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
// 외부 조인
jqpl = "SELECT m FROM Member m LEFT OUTER JOIN m.team t ON t.name = '%신%'";
resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
// 세타 조인
jpql = "SELECT m FROM Member m, Team t WHERE m.id = t.id AND t.name = '%신%'";
resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
서브쿼리
: JPA에서는 WHERE / HAVING 절에서만 사용 가능 > 하이버네이트에서는 SELECT 절도 사용 가능 : FROM 절의 서브쿼리는 현재 JPQL에서 불가능 > JOIN으로 해결 추천 |
+
서브쿼리 지원 함수
: [NOT] EXISTS (서브쿼리)
> 서브쿼리에 결과가 존재하면 참
> ALL / ANY / SONE 추가 사용 가능
(모두 만족 / 조건 한개라도 만족) -> true
: [NOT] IN (서브쿼리)
> 서브쿼리 결과 중 하나라도 같은것이 있다면 참
샘플코드)
// 조건 절 서브쿼리 : exists 사용 예제
String jqpl = "SELECT e FROM 엔티티 e "
+ "WHERE EXISTS (SELECT s FROM e.연관관계객체 s WHERE s.컬럼조건)";
List<Member> resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
// 조건 절 서브쿼리 : exists ALL 사용 예제
// s의 조건에 모두 부합하는 데이터가 존재할 시
jqpl = "SELECT e FROM 엔티티 e "
+ "WHERE m.조건 = ALL(SELECT s FROM e.연관관계객체 s WHERE s.컬럼조건)";
resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
// 조건 절 서브쿼리 : exists ANY 사용 예제
// s의 조건에 하나라도 부합하는 데이터가 존재할 시
jqpl = "SELECT e FROM 엔티티 e "
+ "WHERE m.조건 = ANY(SELECT s FROM e.연관관계객체 s WHERE s.컬럼조건)";
resultList = em.createQuery(jqpl, Member.class).getResultList();
System.out.println("resultList : " + resultList);
※ JPA에서의 쿼리 방법에 대해서는, 아래 포스팅을 참조 부탁드리겠습니다.
https://logger-debug.tistory.com/entry/JPA-JPQL-%EA%B2%BD%EB%A1%9C-%ED%91%9C%ED%98%84%EC%8B%9D
오늘은, JPA의 쿼리 방법 중 하나인, JQPL에 대해 알아보았습니다.
그럼 오늘도 즐거운 하루 되시길 바라겠습니다.
'프로그래밍 > Back-end' 카테고리의 다른 글
JPA 쿼리 JPQL 벌크 연산 (0) | 2024.10.24 |
---|---|
JPA 쿼리 패치 조인 JPQL FETCH JOIN (0) | 2024.10.24 |
JPA JPQL 경로 표현식 (0) | 2024.10.23 |
JPA JPQL 타입 표현식과 기타식 그리고 조건식과 기본 함수 (0) | 2024.10.18 |
JPA QueryDSL 네이티브SQL JDBC MyBatis (0) | 2024.10.18 |
JPA 지연로딩 즉시로딩 (0) | 2024.10.17 |
JPA 지연로딩 즉시로딩 프록시 proxy (0) | 2024.10.17 |
JPA 영속성 전이 CASCADE 고아 객체 (0) | 2024.10.15 |