관리 메뉴

JIE0025

[JPA] JPQL 개념, 기본 기능 본문

백엔드/스프링, 스프링부트, JPA, Spring Webflux

[JPA] JPQL 개념, 기본 기능

Kangjieun11 2022. 10. 27. 01:07
728x90

 

JPQL   ( Java Persistence Query Language )

- 엔티티 객체를 조회하는 객체지향 쿼리

- JPA Query를 작성하는 방법을 제공한다.

 

 

- Table column명 사용 대신, 엔티티이름, 속성을 사용함.

- ANSI 표준 SQL이 제공하는 기능을 유사하게 지원한다

- 엔티티 객체를 대상으로 쿼리한다.

- 엔티티 직접조회, 묵시적 조인, 다형성지원으로 SQL보다 간결하다.

 

 

JPQL 맛보기

 

DB    

username  age id team
jieun 24 jieun11 a
jin 22 jin12 a
kim 25 kin123 b

 

@Column : JPA에서 DB Table의 Column을 Mapping 할 때 @Column Annotation을 사용함
@Entity(name="Member") // name속성의 기본값 : 클래스명
public class Member{
 @Column(name="name")
 private String username;
 //...
}

 

String jqpl = "select m from Member as m where m.username = 'kim'";
List<Member> resultList = em.createQuery(jpql, Member.class).getResultList();

Member =  엔티티 이름, 

m.username == 엔티티 객체의 필드 이름

회원 이름이 'kim'인 엔티티를 조회하라.

 

createQuery(실행할 Jpql, 반환할 엔티티의 클래스 타입)

getResultList() : JPA가 JPQL을 SQL로 변환해 DB 조회 - > 조회한 결과로 엔티티를 생성해 반환

 

 

 

실행 JPQL 

select m from Member as m where m.username = 'kim'

실제로 실행된 SQL

select
    member.id as id,
    member.age as age,
    member.team_id as team,
    member.name as name
from
    Member member
where
    member.name='kim'

 

 

 


 

JPQL 기본 문법


- SELECT, UPDATE, DELETE 가능

- INSERT 불가능 (EntityManager.persist()를 사용해 엔티티를 저장한다. )

 

select  별칭 from 엔티티명 별칭 

select r form Review r 

select m from Member as m 

 

⏺ SELECT

select m from Member as m where m.username='jieun

 

- 엔티티와 속성은 대소문자 구분 O

Member != member

UserName != username

 

 - JPQL키워드는 대소문자 구분 x    (sql 쿼리도 그렇지)

SELECT == select

FROM == from

 

- JPQL은 별칭이 필수다

select username from Member m       // X

select m.username from Member m   // O

 

- AS는 생략 가능하다

Member AS m == Member m

 

 

⏺ 쿼리의 종류 : TypeQuery와 Query

- 작성한 JPQL을 실행하기 위한 쿼리 객체

 

TypeQuery : 반환 타입 명확한 지정 가능

TypedQuery<Member> query
    = em.createQuery("SELECT m FROM Member m", Member.class);

List<Member> resultList = query.getResultList();
for (Member member : resultList) {
    System.out.println("member = " + member);
}

 

Query : 반환 타입 명확한 지정 불가능

Query query
    = em.createQuery("SELECT m.username, m.age FROM Member m");

List<Member> resultList = query.getResultList();
for (Object o : resultList) {
    Object[] result = (Object[]) o;  //결과가 둘 이상이면 Object[] 반환
    System.out.println("username = " + result[0]);
    System.out.println("age = " + result[1]);
}

em.createQuery()

- 두번째 파라미터에 반환타입 지정시 TypeQuery 반환, 지정 안할 경우 Query 반환

- 반환형이 불확실한 경우에 Query를 사용한다.

 

 

결과 조회하기

JPQL에서 쿼리를 통한 결과를 받을 때 사용하는 메서드🔽🔽

 

query.getResultList() : 결과를 리스트로 반환

query.getSingleResult : 결과가 한개일 때 사용 (1개가 아니면 예외 발생 )

- 결과 존재 x : javax.persistence.NoResultException

- 결과가 둘 이상임 : javax.persistence.NonUniqueResultException

 

 


 

기본 JPQL 사용방법

 

쿼리 생성

TypedQuery<T> EntityManager#createQuery(String ql, Class<T> resultClass)

 

 

(출처 유튜브 최범균님)

 

 

검색 조건 지정

where + and, or, 괄호 등

select r from Review r where r.hotelId = :hotelId
select r from Review r where r.hotelId = ?
select r from Review r where r.hotelId = :hotelId and r.mark > :minMark
selet p from Player p where p.position = :pos or p.team.if = :teamId

 

 

파라미터 바인딩

- 쿼리에 작성되는 특정 속성을 매개변수로 매핑 하는 것.

- 쿼리에 매개변수를 매핑하는 방식엔 이름기준, 위치기준 두가지가 존재.

 

 

이름 기준 파라미터 (Named Parameters)

- 파라미터를 이름으로 구분함.

-   =: 연산자  를 사용한다 (파라미터 앞에  을 붙힌다)

 

query.setParameter("hotelId", "H-001")

Query query = em.createQuery("select m from Member m where m.username =: username")
                .setParameter("username", usernameParam);

 

인덱스 기반 파라미터 (Positional Parameters)

- 0부터 시작

=? 연산자  사용  (파라미터 앞에  을 붙힌다)

 

 

query.setParameter(0,"H-001")

Query query = em.createQuery("select m from Member m where m.username =? 1")
                .setParameter(1, usernameParam);

 

** 매개변수 바인딩시 이름 기반 바인딩 사용을 권장함 (나중에 새로운 매개변수 추가시 위치/인덱스 기반 바인딩은 순서가 밀려서)

- 숫자를 이용하면 어떤 위치의 매개변수가 무엇을 의미하는지 쉽게 파악 불가능

- 가독성이 떨어져 유지보수 할 때 비효율적

 

 

 

⏺ 정렬 (SQL과 동일)

order by 기준1 (,기준2..)

asc, desc 사용가능, 

select r from Review r order by r.id
select r from Review r order by r.id asc
select r from Review r order by r.id desc
select p from Player p order by p.position, p.name
select p from Player p order by p.team.id, p.name

 

- default : 오름차순 정렬

 

비교연산자

연산자 example
= u.name = 'JPA'
<  >  o.state < > ?
>  >=  <  <= p.salary > 2000
between mc.expiryDate between ? and ?
in, not in o.mark in (1,2,3)
like, not like u.name like '%유%'
is null, is not null u.name is null

 

 

 


출처


https://devraphy.tistory.com/566?category=1059635

 

https://velog.io/@yu-jin-song/JPA-Chapter-10.-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%EC%BF%BC%EB%A6%AC-%EC%96%B8%EC%96%B4-1-JPQL#-%EA%B2%B0%EA%B3%BC-%EC%A1%B0%ED%9A%8C

 

https://www.youtube.com/watch?v=UtEhC68GTH0&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=18