JPQL(1) - 기본 문법

2024. 1. 24. 20:24spring/JPA

엔티티를 쿼리하는 방법은 다양하다. JPQL, Criteria, QueryDSL, 네이티브 SQL 등등이 있다.

어떤 방법을 사용하든 JPQL에서 모든 것이 시작한다.

 

JPQL 특징

1. JPQL은 객체지향 쿼리 언어다. 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.

2. JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.

3. JPQL은 결국 SQL로 변환된다.

 

 

*예제로 사용할 도메인 모델

 

 

1. 기본 문법과 쿼리 API

SELECT

SELECT 문은 다음과 같이 사용한다.

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

 

- 대소문자 구분

엔티티와 속성은 대소문자를 구분한다.

엔티티 : Member

속성     : name

반면에 SELECT, FROM, AS 같은 JPQL 키워드는 대소문자를 구분하지 않는다.

 

- 엔티티 이름

JPQL에서 사용한 Member는 클래스 명이 아니라 엔티티 명이다. 엔티티 명은 @Entity(name="XXX")로 지정할 수 있고 지정하지 않으면 클래스명을 기본값으로 사용한다.

 

- 별칭은 필수

Member as m을 보면 Member에 m이라는 별칭을 주었다. JPQL은 별칭을 필수로 사용해야 한다. 따라서 다음 코드처럼 별칭 없이 작성하면 잘못된 문법이라는 오류가 발생한다.

select name from Member m

as 는 생략할 수 있다.

 

- TypeQuery, Query

작성한 JPQL을 실행하려면 쿼리 객체를 만들어야 한다.

TypeQuery : 반환할 타입이 명확할 때

Query         : 반환할 타입이 명확하지 않을 때

TypedQuery<Member> tq = 
	em.createQuery("select m from Member as m where m.name = 'kim1'", Member.class);
    
List<Member> list = memberTypedQuery
    .getResultList();

 

em.createQuery() 의 두 번째 파라미터에 반환할 타입을 지정하면 TypeQuery를 반환한다.

 

Query memberTypedQuery =
	em.createQuery("select m.username, m.age from Member m")
        
List list = memberTypedQuery
        .getResultList();

 

조회 대상이 String 타입인 회원 이름과 Integer 타입인 나이이므로 조회 대상 타입이 명확하지 않다. 이때는 Query 객체를 사용한다.

 

Query 객체는 SELECT 절의 조회 대상이 예제처럼 둘 이상이면 Object[]를 반환하고 SELECT 절의 조회 대상이 하나면 Object를 반환한다.

 

- 결과 조회

다음 메소드들을 호출하면 실제 쿼리를 실행해서 데이터베이스를 조회한다.

 

query.getResultList() : 결과를 예제로 반환한다. 결과가 없으면 빈 컬렉션을 반환한다.

query.getSingleResult() : 결과가 정확히 하나일 때 사용한다.

 - 결과가 없으면 javax.persistence.NoResultException 예외가 발생한다.

 - 결과가 1개보다 많으면 javax.persistence.NonUniqueresultException 예외가 발생한다.

 

2. 파라미터 바인딩

JPQL은 이름 기준 파라미터 바인딩도 지원한다.

 

-이름 기준 파라미터

파라미터 이름 앞에 :를 사용한다.

List<Member> list = em.createQuery("select m from Member as m where m.name = :name", Member.class)
        .setParameter("name", "member1")
        .getResultList();

 

 

-위치 기준 파라미터

?다음에 위치 값을 주면 된다.

List<Member> list = em.createQuery("select m from Member as m where m.name = ?1", Member.class)
        .setParameter(1, "member1")
        .getResultList();

'spring > JPA' 카테고리의 다른 글

JPQL(3) - 페이징, 조인  (1) 2024.01.25
JPQL(2) - 프로젝션  (0) 2024.01.24
JPA - 값 타입  (0) 2024.01.20
JPA - 즉시 로딩과 지연 로딩, 영속성 전이, 고아 객체  (0) 2024.01.19
JPA - 프록시  (0) 2024.01.19