• JPQL
  • Criteria 쿼리 : JPQL을 편하게 작성하도록 도와주는 API, 빌더 클래스 모음
  • 네이티브 SQL: JPA에서 JPQL 대신 직접 SQL 사용
  • QueryDSL : Criteria 쿼리처럼 JPQL을 작성하도록 도와주는 빌더 클래스, 비표준 오픈소스
  • JDBC 직접 사용, MyBatis 같은 SQL 매퍼 프레임워크 사용

 현재는 JPQL만 정리 나머지는 JPQL을 편하게 사용해주는 기술


JPQL

1.select문

SELECT m FROM Member AS m where m.username = ‘hello’

  • 엔티티 소성은 대소문자 구분(Member, username)
  • 엔티티 이름 Member는 @Entity(name=”Member”)로 지정
  • 별칭 필수 (Member AS m 또는 Member m)


2.TypedQuery,Query

TypedQuery<Member> query = em.createQuery(SELECT m FROM Member m, Member.class);
    List<Member> resultList = query.getResultList();
    for(Member member : resultList) {
}
Query query = em.createQuery(SELECT m.username, m age from Member m);
List resultList = query.getResultList();
for(Object o : resultList){
	Object[] result = (Object[]) o;
}


3.파라미터 바인딩

  • 이름기준
TypedQuery<Member> query = em.createQuery(SELECT m FROM Member m where m.username = :username, Member.class);
query.setParameter(username,usernameParam);
  • 위치기준
List<Member> members = em.createQuery(SELECT m FROM Member m where m.username =?1,Member.class).setParameter(1, usernameParam).getResultList();


4.페이징 API

TypedQuery<Member> query = em.createQuery(SELECT m FROM Member m ORDER BY m.username DESC, Member.class);
query.setFirstResult(10);	//조회 시작 위치
query.setMaxResults(20);	//조회할 데이터 수
query.getResultList();


5.집합/정렬

ex) 평균 나이가 10살 이상인 그룹 조회

select t.name, COUNT(m.age), SUM(m.age), AVG(m.age), MAX(m.age), MIN(m.age) from Member m LEFT JOIN m.team t GROUP BY t.name HAVING AVG(m.age) >= 10

select t.name, COUNT(m.age) as 춧 from Member m LEFT JOIN m.team t GROUP BY t.name ORDER BY cnt


6.조인

  • 내부조인

SELECT m FROM Member m INNER JOIN m.team t WHERE t.name = :teamName

  • 외부조인

SELECT m FROM Member m LEFT [OUTER] JOIN m.team t

  • 컬렉션 조인

SELECT t, m FROM Team t LEFT JOIN t.members m

팀과 팀이 보유한 회원 목록을 컬렉션 값 연관 필드로 외부 조인

  • 세타조인

SELECT COUNT(m) from Member m, Team t where m.username = t.name

관계없는 엔티티 조인 가능

  • JOIN ON 절(JPA 2.1)

SELECT m,t from Member m left join m.team t on t.name = ‘A’

  • 페치 조인 – 연곤된 엔티티나 컬렉션을 한번에 같이 조회

select m from Member m join fetch m.team

 SELECT M.,T. FROM MEMBER T INNER JOIN TEAM T ON M.TEAM_ID = T.ID

  • 컬렉션 페치 조인

select t from Team t join fetch t.members where t.name = ‘팀A’

 SELECT T.,M. FROM TEAM T INNER JOIN MEMBER M ON T.ID=M.TEAM_ID WHERE T.NAME = ‘팀A’

  • 페치 조인과 DISTINCT

select distinct t from Team t join fetch t.members where t.name = ‘팀A’


7.서브쿼리

  • EXISTS

서브쿼리에 결과가 존재하면 TURE NOT은 반대

select m from Member m where exists (select t from m.team t where t.name = ‘팀A’)

  • ALL, ANY, SOME
    • ALL : 조건을 모두 만족하면 참
    • ANY or SOME : 조건을 하나라도 만족하면 참

select o from Order o where o.orderAmount > ALL (select p.stockAmount from Product p)

  • IN

서브 쿼리 결과 중 하나라도 같은 것이 있으면 참

select t from Team t where t IN (select t2 From Team t2 JOIN t2.members m2 where m2.age >= 20)


8.조건식

  • Between

select m from Member m where m.age between 10 and 20

  • IN

select m from Member m where m.username in (‘회원1’,’회원2’)

  • LIKE

% : 아무 값들이 입력되어도 된다 ( 값이 없어도 됨)

_ : 한 글자는 아무 값이 입력되어도 되지만 값이 있어야함

where m.username like ‘%원%’ //회원3

where m.username like ‘회원_’ //회원3


9.컬렉션 식

  • 빈 컬렉션 비교 식

select m from Member m where m.orders is not empty

  • 컬렉션의 멤버 식

select t from Team t where :memberParam member of t.members

엔티티나 값이 컬렉션에 포함되어 있으면 참


10.스칼라식

  • 수학 식

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

CONCAT(문자1, 문자2, …) 문자 합치기

SUBSTRING(문자, 위치, [길이]) 특정 위치 문자

TRIM([[LEADING TRAILING BOTH] [트림 문자] FROM] 문자)
  • LEADING: 왼쪽만 , TRAILING 오른쪽만, BOTH 양쪽 다 트림 문자 제거, 기본값은 BOTH, 트림문자 기본 값은 SPACE

LOWER (문자) 소문자

UPPER(문자) 대문자

LENGTH(문자) 문자 길이

LOCATE(찾을 문자, 원본 문자, [검색시작위치]) 문자 위치

  • 수학함수

ABS(수학식) 절대값

SQRT(수학식) 제곱근

MOD(수학식, 나눌 수) 나머지

SIZE(컬렉션 값 연관 경로식) 컬렉션 크기

INDEX(별칭) LIST 타입 컬렉션의 위치값 단 컬렉션이 @OrderColumn을 사용하는 LIST 타입


11.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 Member m

  • COALESCE (null 이 아니면 반환)

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

  • NULLIF (두 값이 같으면 null을 반환 다르면 첫 번째 값을 반환)

select NULLIF(m.username, ‘관리자’) from Member m


12.다형성 쿼리

  • Item의 자식으로 Book, Album, Movie 가 있을 때
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = DTYPE)
public abstract class Item{}

@Entity
@DiscriminatorValue(B)
public class Book extends Item {
    
	private String author;
}
List resultList = em.createQuery(select i from Item i).getResultList();

//SQL

SELECT i.ITEM_ID, i.DTYPE, i.name, i.price, i.stockQuantity, b.author, b.isbn, a.artist, a.etc, m.actor, m.director FROM Item i left outer join Book b on i. ITEM_ID=b.ITEM_ID left outer join Album a on i. ITEM_ID=a.ITEM_ID left outer join Movie m on i. ITEM_ID=m.ITEM_ID

  • TYPE (엔티티 상속 구조에서 조회 대상을 특정 자식 타입으로 한정)

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

  • TREAT(JPA 2.1)

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

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


출처 : 자바 ORM 표준 JPA 프로그래밍 김영한 지음