JPA - 객체지향 쿼리언어(5)

DevSeoRex·2022년 12월 11일
0
post-thumbnail

🐸 조건식

🐶 타입 표현

  • JPQL에서 사용하는 타입은 아래의 표와 같이 표현합니다.
종류설명예제
문자 작은 따옴표 사이에 표현
작은 따옴표를 표현하고 싶으면 작은 따옴표 연속 두 개('') 사용
'HELLO'
'She ''s'
숫자L(Long 타입 지정)
D(Double 타입 지정)
F(Float 타입 지정)
10L
10D
10F
날짜DATE{ d 'yyyy-mm-dd' }
TIME{ t 'hh-mm-ss' }
DATETIME{ is 'yyyy-mm-dd hh:mm:ss.f' }
{ d '2012-03-24' }
{t '10-11-11' }
{ts '2012-03-24 10-11-11,123' }
m.createDate = { d '2012-03-24'}
BooleanTRUE, FALSE
Enum패키지명을 포함된 전체 이름을 사용해야 한다.jpabook.MemberType.Admin
엔티티 타입엔티티의 타입을 표현한다. 주로 상속과 관련해서 사용한다.TYPE(m) = Member

📝 연산자의 우선 순위

연산자의 우선 순위는 다음과 같습니다.

  1. 경로 탐색 연산 (.)
  2. 수학 연산 : +, -(단항 연산자), *, /, +, -
  3. 비교 연산 : =, >, >=, <, <=, <>(다름), [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER [OF], [NOT] EXISTS
  4. 논리 연산 : NOT, AND, OR

🔵 논리 연산과 비교식

논리 연산

  • AND : 둘 다 만족하면 참
  • OR : 둘 중 하나만 만족해도 참
  • NOT : 조건식의 결과 반대

비교식

  • 비교식은 아래와 같습니다.
    = | > | >= | < | <= | <>

🌈 Between, IN, Like, NULL 비교

Between 식

  • 문법 : X [NOT] BETWEEN A AND B
  • 설명 : X는 A ~ B 사이의 값이면 참(A,B 값 포함)
// 예제 : 나이가 10 ~ 20인 회원을 찾기
select m from Member m
where m.age between 10 and 20

IN 식

  • 문법 : X [NOT] IN(예제)
  • 설명 : X와 같은 값이 예제에 하나라도 있으면 참이다. IN 식의 예제에는 서브쿼리를 사용할 수 있습니다.
// 예제 : 이름이 회원1이나 회원2인 회원을 찾기
select m from Member m
where m.username in('회원1', '회원2')

Like 식

  • 문법 : 문자표현식 [NOT] LIKE 패턴값 [ESCAPE 이스케이프문자]
  • 설명 : 문자표현식과 패턴값을 비교합니다.
  • %(퍼센트) : 아무 값들이 입력되어도 됩니다(값이 없어도 됨).
  • _(언더라인) : 한 글자는 아무 값이 입력되어도 되지만 값이 있어야 합니다.
// Like 식 예제

// 중간에 원이라는 단어가 들어간 회원(좋은회원, 회원, 원)
select m from Member m
where m.username like '%원%'

// 처음에 회원이라는 단어가 포함(회원1, 회원ABC)
where m.username like '회원%'

// 마지막에 회원이라는 단어가 포함(좋은 회원, A회원)
where m.username like '%회원'

// 회원A, 회원1
where m.username like '회원_'

// 회원3
where m.username like '__3'

// 회원%
where m.username like '회원\%' ESCAPE '\'

NULL 비교식

  • 문법 : { 단일 값 경로 | 입력 파라미터 } IS [NOT] NULL
  • 설명 : NULL 인지 비교합니다. NULL은 =으로 비교하면 안 되고 꼭 IS NULL을 사용해야 합니다.
// NULL 비교식 예제
where m.username is null
where null = null // 거짓
where 1=1 // 참

컬렉션 식

컬렉션 식은 컬렉션에만 사용하는 특별한 기능입니다. 참고로 컬렉션은 컬렉션 식 이외에 다른 식은 사용할 수 없습니다.

🎈 빈 컬렉션 비교 식

  • 문법 : { 컬렉션 값 연관 경로 } IS [NOT] EMPTY
  • 설명 : 컬렉션에 값이 비었으면 참
// 빈 컬렉션 비교 예제

// JPQL : 주문이 하나라도 있는 회원 조회
select m from Member m
where m.orders is not empty

// 실행된 SQL
select m.* from Member m
where
	exists (
    	select o.id
        from Orders o
        where m.id = o.member_id
    )

컬렉션은 컬렉션 식만 사용할 수 있습니다.
다음의 is null처럼 컬렉션 식이 아닌 것은 사용할 수 없습니다.

// is null을 컬렉션 식에 사용 - ERROR
select m from Memer m
where m.orders is null (오류 !)

컬렉션의 멤버 식

  • 문법 : { 엔티티나 값 } [NOT] MEMBER [OF] { 컬렉션 값 연관 경로 }
  • 설명 : 엔티티나 값이 컬렉션에 포함되어 있으면 참입니다.
// 컬렉션의 멤버 식 예제
select t from Team t
where :memberParam member of t.members

스칼라 식

스칼라는 숫자, 문자, 날짜, case, 엔티티 타입(엔티티의 타입 정보) 같은 가장 기본적인 타입들을 말한다. 스칼라 타입에 사용하는 식을 알아보겠습니다.

✅ 수학 식

  • +, - : 단항 연산자
  • *, /, +, - : 사칙연산

🎯 문자함수
문자를 다루는 데 사용하는 함수들은 아래와 같습니다.

함수설명예제
CONCAT(문자1, 문자2, ...)문자를 합한다.CONCAT('A','B') = AB
SUBSTRING(문자,위치,[길이])위치부터 시작해 길이만큼 문자를 구한다.
길이 값이 없으면 나머지 전체 길이를 뜻한다.
SUBSTRING('ABCDEF', 2, 3) = BCD
TRIM[(LEADING(TRAILING & BOTH)][트림문자] FROM] 문자)LEADING : 왼쪽만
TRAILING : 오른쪽만
BOTH : 양쪽 다 트림 문자를 제거한다. 기본값은 BOTH, 트림 문자의 기본값은 공백(SPACE)다.
TRIM(' ABC ') = 'ABC'
LOWER(문자)소문자로 변경LOWER('ABC') = 'abc'
UPPER(문자)대문자로 변경UPPER('abc') = 'ABC'
LENGTH(문자)문자 길이LENGTH('ABC') = 3
LOCATE(찾을 문자, 원본 문자,[검색시작위치])검색위치부터 문자를 검색한다.
1부터 시작, 못 찾으면 0 반환
LOCATE('DE', 'ABCDEFG') = 4

💡 HQL은 CONCAT 대신에 | | 도 사용할 수 있습니다.

🦕 수학함수

  • 수학함수는 아래와 같습니다.
함수설명예제
ABS(수학식)절대값을 구한다.ABS(-10) = 10
SQRT(수학식)제곱근을 구한다.SQRT(4) = 2.0
MOD(수학식, 나눌 수)나머지를 구한다.MOD(4,3) = 1
SIZE(컬렉션 값 연관 경로식)컬렉션의 크기를 구한다.SIZE(t.members)
INDEX(별칭)LIST 타입 컬렉션의 위치 값을 구한다.
단 컬렉션이 @OrderCoulmn을 사용하는
LIST 타입일 때만 사용할 수 있다.
t.members m where INDEX(m) < 3

🐳 날짜함수
날짜함수는 데이터베이스는 현재 시간을 조회합니다.

  • CURRENT_DATE : 현재 날짜
  • CURRENT_TIME : 현재 시간
  • CURRENT_TIMESTAMP : 현재 날짜 시간
// 날짜함수의 예제
select CURRENT, CURRENT_TIME, CURRENT_TIMESTAMP from Team t

// 결과 : 2013-08-19, 23:38:17, 2013-08-19 23:38:17.736

💡 Hibernate 날짜 타입에서 년, 월, 일, 시간, 분, 초 값을 구하는 기능을 지원합니다.

// 년, 월, 일을 구하는 예제
select year(CURRENT_TIMESTAMP), month(CURRENT_TIMESTAMP),
	day(CURRENT_TIMESTAMP)
from Member

위의 함수들은 하이버네이트가 제공하는 데이터베이스 방언에 등록되어 있습니다.
오라클 방언을 사용하면 to_date, to_char 함수를 사용할 수 있습니다.

CASE 식

특정 조건에 따라 분기할 때 CASE 식을 사용합니다. CASE 식에는 4가지 종류가 있습니다.

  • 기본 CASE
  • 심플 CASE
  • COALESCE
  • NULLIF

🐧 기본 CASE

// 기본 CASE의 문법
CASE
	{WHEN <조건식> THEN <스칼라식>}+
    ELSE <스칼라식>
END

// 기본 CASE의 예제
select 
	case when m.age <= 10 then '학생요금'
    	 when m.age >= 60 then '경로요금'
         else '일반요금'
 	end
from Member m

🐙 심플 CASE
심플 CASE는 조건식을 사용할 수 없습니다. 문법이 단순합니다.
참고로 자바의 switch case 문과 비슷합니다.

// 심플 CASE 문법
CASE <조건대상>
	{WHEN <스칼라식1> THEN <스칼라식2>}+
    ELSE <스칼라식>
END

// 심플 CASE의 예제
select
	case t.name
    	when '팀A' then '인센티브110%'
        when '팀B' then '인센티브120%'
        else '인센티브105%'
    end
 from Team t

🦫 COALESCE

  • 문법 : COALESCE(<스칼라식> { ,<스칼라식>} +)
  • 설명 : 스칼라식을 차례대로 조회해서 null이 아니면 반환됩니다.
// COALESCE 사용 예제

// 예 m.username이 null이면 '이름 없는 회원을' 반환
select coalesce(m.username, '이름 없는 회원') from Member m

📦 NULLIF

  • 문법 : NULLIF(<스칼라식>, <스칼라식>)
  • 설명 : 두 값이 같으면 null을 반환하고 다르면 첫 번째 값을 반환합니다. 집합 함수는 null을 포함하지 않으므로 보통 집합 함수와 함께 사용합니다.

출처 : 자바 ORM 표준 JPA 프로그래밍(에이콘, 김영한 저)

0개의 댓글