JPA 26

JPQL - Criteria 기초 (조회, 집합, 정렬)

Criteria 쿼리는 JPQL을 자바 코드로 작성하도록 도와주는 빌더 클래스 API이다. Criteria를 사용하면 문자가 아닌 코드로 JPQL을 작성하므로 문법 오류를 컴파일 단계에서 잡을 수 있고 문자 기반의 JPQL보다 동적 쿼리를 안전하게 생성할 수 있는 장점이 있다.   Criteria 기초Criteria API는 javax.persistence.criteria 패키지에 있다. 아래는 단순한 Criteria 쿼리이다.//JPQL: select m from Member mCriteriaBuilder cb = em.getCriteriaBuilder(); // 1. Criteria 쿼리 빌더// 2. Criteria 생성, 반환 타입 지정CriteriaQuery cq = cb.createQuery(..

JPA 2024.05.28

JPQL - Named 쿼리 - 정적 쿼리

JPQL 쿼리는 크게 정적 쿼리와 동적 쿼리로 나눌 수 있다.- 동적 쿼리: em.createQuery(“select…”) 처럼 jpql을 문자로 완성해서 직접 넘기는 것. 런타임에 특정 조건에 따라 jpql을 동적으로 구성할 수 있다.- 정적 쿼리: 미리 정의한 쿼리에 이름을 부여해서 필요할 때 사용할 수 있는데 이것을 Named 쿼리라 한다. Named 쿼리는 한 번 정의하면 변경할 수 없는 정적인 쿼리다.Named 쿼리는 애플리케이션 로딩 시점에 JPQL 문법을 체크하고 미리 파싱해둔다. 따라서 오류를 빨리 확인할 수 있고, 사용하는 시점에는 파싱된 결과를 재사용하므로 성능상 이점도 있다. 그리고 Named 쿼리는 변하지 않는 정적 SQL이 생성되므로 데이터베이스의 조회 성능 최적화에도 도움이 된다..

JPA 2024.05.14

JPQL - CASE 식

특정 조건에 따라 분기할 때 CASE 식을 사용한다. CASE 식은 4가지 종류가 있다. 기본 CASE 심플 CASE COALESCE NULLIF ▼ 기본 CASE CASE {WHEN THEN }+ ELSE select case when m.age = 60 then '경로요금' else '일반요금' end from Member m ▼ 심플 CASE 심플 CASE는 조건식을 사용할 수 없지만 문법이 단순하다. 자바의 switch case문과 비슷하다. CASE {WHEN THEN }+ ELSE END select case t.name when '팀A' then '인센티브110%' when '팀B' then '인센티브120%' else '인센티브105%' end from Team t ▼ COALESCE CO..

JPA 2024.03.25

JPQL - 서브 쿼리

JPQL도 SQL 처럼 서브 쿼리를 지원한다. 여기에는 몇가지 제약이 있는데, 서브쿼리를 WHERE, HAVING 절에서만 사용할 수 있고, SELECT, FROM 절에서는 사용할 수 없다. 다음은 나이가 평균보다 많은 회원을 찾는다. select m from Member m where m.age > (select avg(m2.age) from Member m2) 다음은 한 건이라도 주문한 고객을 찾는다. select m from Member m where (select count(o) from Order o where m = o.member) > 0 # 참고로 이 쿼리는 다음처럼 컬렉션 값 연관 필드의 size 기능을 사용해도 같은 결과를 얻을 수 있다. select m from Member m whe..

JPA 2023.10.23

JPQL - 경로 표현식

경로 표현식이라는 것은 .(점)을 찍어 객체 그래프를 탐색하는 것이다. select m.username from Member m join m.team t join m.orders o where t.name = '팀A' 위의 JPQL에서 m.username, m.team, m.orders, t.name이 모두 경로 표현식을 사용한 예다. 경로 표현식의 용어 정리 상태 필드: 단순히 값을 저장하기 위한 필드(필드 or 프로퍼티) 연관 필드: 연관관계를 위한 필드, 임베디드 타입 포함(필드 or 프로퍼티) - 단일 값 연관 필드: @ManyToOne, @OneToOne, 대상이 엔티티 - 컬렉션 값 연관 필드: @OneToMany, @ManyToMany, 대상이 컬렉션 @Entity public class M..

JPA 2023.10.23

JPQL - 페치 조인(Fetch Join)

페치 조인은 SQL에서 이야기하는 조인의 종류는 아니고 JPQL에서 성능 최적화를 위해 제공하는 기능이다. 이것은 연관된 엔티티나 컬렉션을 한 번에 같이 조회하는 기능인데 join fetch 명령어로 사용할 수 있다. 엔티티 패치 조인 패치 조인을 사용해서 회원 엔티티를 조회하면서 연관된 팀 엔티티도 함께 조회하는 JPQL을 보자. select m from Member m join fetch m.team 예제를 보면 join 다음에 fetch라 되어있는데, 이렇게 하면 연관된 엔티티나 컬렉션을 함께 조회하는데 여기서는 회원(m)과 팀(m.team)을 함께 조회한다. 참고로 일반적인 JPQL 조인과는 다르게 m.team 다음에 별칭이 없는데 페치 조인은 별칭을 사용할 수 없다. 실행된 SQL은 다음과 같다..

JPA 2023.10.12

JPQL 조인

내부 조인 내부조인은 INNER JOIN을 사용하고, INNER는 생략할 수 있다. String teamName = "팀A"; String query = "SELECT m FROM Member m INNER JOIN m.team t " +"WHERE t.name = :teamName"; List members = em.createQuery(query, Member.class) .setParameter("teamName", teamName) .getResultList(); 회원과 팀을 내부 조인해서 '팀A'에 소속된 회원을 조회한다. 외부 조인 SELECT m FROM Member m LEFT [OUTER] JOIN m.team t 다음과 같이 사용하고, OUTER는 생략 가능하다. 컬렉션 조인 일대다 관..

JPA 2023.10.10

JPQL - (기본 문법, 쿼리 API, 페이징 API, 집합과 정렬)

기본 문법과 쿼리 API JPQL도 SQL과 비슷하게 SELECT, UPDATE, DELETE 문을 사용할 수 있다. 참고로 엔티티를 저장할 때는 EntityManager.persist() 메소드를 사용하면 되므로 INSERT 문은 없다. select_문 :: = select_절 from_절 [where_절] [groupby_절] [having_절] [orderby_절] update_문 :: = update_절 [where_절] delete_문 :: = delete_절 [where_절] SELECT 문 SELECT 문은 다음과 같이 사용한다. SELECT m FROM Member AS m where m.username = 'Hello' 엔티티와 속성은 대소문자를 구분한다. (Member, username..

JPA 2023.09.25

객체지향 쿼리 언어 소개

JPA는 복잡한 검색 조건을 사용해서 엔티티 객체를 조회할 수 있는 다양한 쿼리 기술을 지원한다. EntityManager.find() 메소드를 사용하면 식별자로 엔티티 하나를 조회할 수 있다. 이렇게 조회한 엔티티에 객체 그래프 탐색을 사용하면 연관된 엔티티들을 찾을 수 있다. 이 둘은 가장 단순한 검색 방법이다. 식별자로 조회 EntityManager.find() 객체 그래프 탐색 a.getB().getC() 이 기능만으로 애플리케이션을 개발하기는 어렵다. 예를 들어 나이가 24살 이상인 회원을 모두 검색하고 싶다면 좀 더 현실적이고 복잡한 검색 방법이 필요하다. 결국 데이터는 데이터베이스에 있으므로 SQL로 필요한 내용을 최대한 걸러서 조회해야 한다. 하지만 ORM을 사용하면 데이터베이스 테이블이 ..

JPA 2023.09.22

값 타입

값 타입은 3가지로 나눌 수 있다. 기본값 타입(자바 기본 타입, 래퍼 클래스, String) 임베디드 타입 컬렉션 값 타입 1. 기본값 타입 @Entity public class Member { @Id @GeneratedValue private Long id; private String name; private int age; ... } Member 엔티티에서 String, int가 값 타입이다. Member 엔티티는 id라는 식별자 값도 가지고 생명주기도 있지만 값 타입인 name, age 속성은 식별자 값도 없고 생명주기도 회원 엔티티에 의존한다. 따라서 회원 엔티티 인스턴스를 제거하면 name, age 값도 제거된다. 그리고 값 타입은 공유하면 안된다. 2. 임베디드 타입(복합 값 타입) 새로운 ..

JPA 2023.09.22