본문 바로가기

스터디/JPA

객체지향 쿼리 언어 - (6)

728x90
반응형

JPQL - (5)


조건식

타입표현

 

대소문자 구분 없음

 

- 문자: 작은 따옴표 사이에 표현, 작은 따옴표는 ‘’으로 표현

- 숫자: L(Long), D(Double), F(Float)

- 날짜: DATE {d ’yyyy-mm-dd’}, TIME {t ’hh—mm—ss’}, DATETIME {ts ‘yyyy-mm-dd hh:mm:ss.f’}

- Boolean: TRUE, FALSE

- Enum: 패키지명을 포함한 전체 이름을 사용

- 엔티티 타입: 엔티티 타입을 표현, 상속과 관련 (TYPE(m) = Member)

 

 

BETWEEN, IN, LIKE, NULL

 

- between

x [not] between a and b: x가 a와 b 사이의 값이면 참 (포함)

 

- in

x [not] in (): x와 같은 값이 하나라도 있으면 참

 

- like

문자표현식 [not] like 패턴값 [escpae 이스케이프문자]: 문자표현식과 패턴 값을 비교한다

%: 아무 값들이나 괜찮다 (없어도 된다)

_: 한 글자는 아무 값이어도 괜찮지만 값이 있어야 한다

 

- null

(단일값 경로 | 입력 파라미터) is [not] null: null인지 비교한다 (=으로 비교 불가)

 

 

컬렉션 식

 

빈 컬렉션 비교 식

(컬렉션 값 연관 경로) is [not] empty: 컬렉션 값이 비었으면 참

 

컬렉션 멤버 식

(엔티티나 값) [not] member [of] (컬렉션 값 연관 경로): 엔티티나 값이 컬렉션에 포함되어 있으면 참

 

 

스칼라 식

 

수학 식

 

문자함수: concat, substring, trim, lower, upper, lenght, locate

수학함수: abs, sqrt, mod, size, index

날짜함수: current_date, current_time, current_timestamp

 

 

CASE 식

 

기본 CASE

select
	case when m.age <= 10 then '학생요금'
	     when m.age >= 60 then '경로요금'
	     else '일반요금'
	end
from Member m

 

심플 CASE

select
	case t.name
	     when '팀A' then '인센티브110%'
	     when '팀B' then '인센티브120%'
	     else '인센티브105%'
	end
from Team t

 

 

COALESCE

select coalesce(m.username, '이름 없는 회원') from Member m

m.username이 null이면 이름 없는 회원을 반환해라

 

NULLIF

select nullif(m.username, '관리자') from Member m

m.username이 관리자면 null을 반환하고 나머지는 본인의 이름을 반환해라

다형성 쿼리

JPQL로 부모 엔티티를 조회하면 그 자식 엔티티도 함께 조회한다

 

TYPE

 

조회 대상을 특정 자식 타입으로 한정할 때 사용한다

select i from Item i
where type(i) in (Book, Movie)

 

 

TREAT

 

상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용한다

select i from Item where treat(i as Book).author = 'kim'

사용자 함수 호출

select function('group_concat', i.name) from Item i
public class MyH2Dialect extends H2Dialect {
	
	public MyH2Dialect() {
		registerFunction("group_concat", new StandardSQLFunction
			("group_concat", StandardBasicTypes.STRING));
	}
}

엔티티 직접 사용

기본 키 값

 

JPQL에서 엔티티 객체를 직접 사용하면 SQL에서는 해당 엔티티의 기본 키 값을 사용한다

//동일한 sql을 실행한다
select count(m) from Member m
select count(m.id) from Member m

 

 

외래 키 값

//동일한 sql을 실행한다
select m from Member m where m.team = :team
select m from Member m where m.team.id = :teamId

Named 쿼리: 정적 쿼리

동적 쿼리: JPQL을 문자로 완성해서 직접 넘기는 것

 

정적 쿼리: 미리 정의한 쿼리에 이름을 부여해 필요할 때 사용하는 것, Named 쿼리

  - 애플리케이션 로딩 시점에 JPQL 문법을 체크하고 미리 파싱해둔다

  - 오류를 빨리 확인할 수 있고 파싱된 결과를 재사용할 수 있다

 

 

Named 쿼리를 어노테이션에 정의

 

@Entity
@NamedQuery(
	name="Member.findByUsername",
	query="select m from Member m where m.username = :username")
public class Member {
	...
}
List<Member> resultList = em.createNameQuery("Member.findByUsername", Member.class)
	.setParameter("username", "회원1")
	.getResultList();

정적 쿼리 이름 앞에 엔티티 이름을 붙이면 관리하기 편하다

 

@NamedQueries를 사용해 여러 개의 정적 쿼리를 정의할 수 있다

 

속성

  - lockMode: 쿼리 실행 시 락을 건다 

  - hints: JPQ 구현체에게 제공하는 힌트, 2차 캐시를 다룰 때 사용한다

 

 

Named 쿼리를 XML에 정의

 

Named 쿼리를 작성할 때에는 XML을 사용하는 것이 편리하다

멀티라인을 지원한다

 

<named-query name="Member.count">
	<query>select count(m) from Member m</query>
</named-query>

persistence.xml에 위와 같이 Named 쿼리를 정의하면 된다

728x90
반응형

'스터디 > JPA' 카테고리의 다른 글

스프링 데이터 JPA - (1)  (0) 2025.02.20
객체지향 쿼리 언어 - (7)  (1) 2025.02.19
객체지향 쿼리 언어 - (5)  (0) 2025.02.18
객체지향 쿼리 언어 - (4)  (0) 2025.02.18
객체지향 쿼리 언어 - (3)  (0) 2025.02.17