QL 기본 문법 - 1
JPQL
SQL - 데이터베이스 테이블을 대상으로 쿼리
JPQL - 엔티티 객체를 대상으로 쿼리
JPQL로 작성해도 결국 SQL로 변환되어 DB에 적용
String jpql = "select m From Member m where m.name like '%hello%'";
List<Member> result = em.createQuery(jpql, Member.class)
.getResultList();
for (Member member : result) {
System.out.println("member = " + member);
}
SQL과 매우 유사한 문법
하지만 이와 같은 코드 작성은 동적 쿼리를 생성하는 데에 어려움이 있음
=> QueryDSL 등장(추후 설명)
문법
select m from Member as m where m.age > 18
- 엔티티는 대소문자 구분됨
- JPQL 키워드는 대소문자 구분 X
- 테이블 명이 아닌 엔티티 이름 사용
- 별칭은 필수(m), as는 생략 가능
TypeQuery, Query
- TypeQuery : 반환 타입이 명확할 때 사용
- Query : 반환 타입이 명확하지 않을 때 사용
TypedQuery<Member> query1 =
em.createQuery("select m from Member m", Member.class);
TypedQuery<String> query2 =
em.createQuery("select m.username from Member m", String.class);
Query query3 =
em.createQuery("select m.username, m.age from Member m");
// m.username과 m.age => 어떤 타입 반환해야 할지 애매함
이들을 getResultList(), getSingleList()를 통해 조회할 수 있음
query.getResultList() : 결과가 하나 이상일 때, 리스트 반환
(결과가 없으면 빈 리스트 반환)
query.getSingleList() : 결과가 정확히 하나일 때 단일 객체 반환
(결과가 없거나 둘 이상이면 예외 발생)
아래와 같이 조회하면 됨
List<Member> resultList = query1.getResultList();
for (Member member1 : resultList) {
System.out.println("member1 = " + member1);
}
파라미터 바인딩
이름 기준
TypedQuery<Member> query =
em.createQuery("select m from Member m where m.username = :username", Member.class);
query.setParameter("username", "member1");
Member singleResult = query.getSingleResult();
System.out.println("singleResult = " + singleResult);
또는 아래와 같이 표현함
Member singleResult = em.createQuery("select m from Member m where m.username = :username", Member.class);
.setParameter("username", "member1").
.getSingleResult();
System.out.println("singleResult = " + singleResult.getUsername);
위치를 기준으로 표현할 수도 있지만,
이는 장애를 발생시킬 가능성이 높으므로 사용 권장하지 않음
(중간에 엔티티 삽입되면 순서가 전부 바뀌는 경우 등의 이유)
프로젝션
SELECT 절에 조회할 대상을 지정하는 것
예시
1. SELECT m From Member m;
: 엔티티 프로젝션
2. SELECT m.team From Member m;
: 엔티티 프로젝션
3. SELECT m.address From Member m;
: 임베디드 타입 프로젝션
여러 값 조회
ex) m.username, m.age를 조회 하려고 하면?
=> Object 타입 사용
List resultList = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o;
또는
List<Object[]> resultList =
em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object[] result = resultList.get(0);
따로 객체를 만드는 방법도 있다.
List<MemberDTO> result = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m, MemberDTO.class)
.getResultList();
MemberDTO memberDTO = result.get(0);
MemberDTO에 생성자 필수
페이징
- setFirstResult(int startPosition) : 조회 시작 위치(0부터 시작)
- setMaxResults(int maxResult) : 조회할 데이터 수
예시
//페이징 쿼리
String jpql = "select m from Member m order by m.name desc";
List<Member> resultList = em.createQuery(jpql, Member.class)
.setFirstResult(10)
.setMaxResults(20)
.getResultList();
서브쿼리
EXISTS, ALL, ANY, SOME, NOT IN 등 지원 가능
JPQL은 WHERE, HAVING, SELECT 절에서 서브쿼리 사용이 가능하고
From에서의 서브쿼리는 지원하지 않는다.
ex)
select ~~ from (select ~~) as ~~
실행 X
타입 체크 - select i from Item I where type(i) = Book
조건식 - CASE도 작성 가능하다.
String query =
"select " +
"case when m.age <= 10 then '학생요금' " +
" when m.age >= 60 then '경로요금' " +
" else '일반요금' " +
" end " +
"from Member m";
-
coalesce : 하나씩 조회해서 null이 아니면 반환
select coalesce (m.username,'이름 없는 회원') from Member m
-
NULLIF : 두 값이 같으면 null 반환, 다르면 첫 번째 값 반환
select NULLIF(m.username, '관리자') from Member m
CONCAT, SUBSTRING, TRIM등의 함수 역시 JPQL에서도 사용 가능
Author And Source
이 문제에 관하여(QL 기본 문법 - 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@bty5596/JPQL-기본-문법-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)