728x90
반응형
728x90
JPQL (Java Persistence Query Language)
- JPA에서 사용하는 쿼리 언어로 테이블을 대상으로 하는 SQL과 다르게 자바 객체를 대상으로 쿼리
- JPQL 쿼리는 EntityManager를 통해 실행
- 기본적인 쿼리는 SELECT, UPDATE, DELETE, JOIN 등의 SQL 구문과 유사하나 객체를 대상으로 사용
- 쿼리 내 엔티티와 엔티티의 속성은 대소문자를 구분
- 별칭을 필수로 사용
- 엔티티, 임베디드, 스칼라 타입에 대해 프로젝션 가능
사용법
- EntityManager의 createQuery()의 파라미터에 JPQL 문을 넣어 사용
- 예시) em.createQuery("select m from Member m") -> 반환 타입 Query 인터페이스
- 반환 타입을 명시적으로 지정하여 사용 가능
- 예시) em.createQuerty("select m from Member m", Member.class) -> 반환 타입 TypedQuery<Member>
- 파라미터를 바인딩하여 사용 가능
- 예시) em.createQuerty("select m from Member m where m.id = :id", Member.class).setParameter("id", 1)
- 주요 메서드
- .getResultList(): 반환 값을 List 형태로 변환하여 반환
- .getSingleResult(): 단일 결과를 반환 -> 결과가 없거나 1개 이상일 경우 오류 발생
- .setFirstResult(): 페이징 처리, 쿼리 결과의 시작 위치 지정
- .setMaxResults(): 페이징 처리, 쿼리 결과의 최대 개수 설정
- .setHint(): 쿼리 실행에 대한 힌트 지정
조건식
//CASE 문
CASE
WHEN condition THEN result
[WHEN ...]
[ELSE default_result]
END
- SQL의 case문과 유사
- 조건에 따라 값을 선택
NULLIF(expression1, expression2)
- 두 값이 같을 때 NULL을 반환하고 그렇지 않으면 첫 번째 값을 반환
COALESCE(expression1, expression2, ..., expressionN)
- 인수 목록에서 첫 번째 NULL이 아닌 값을 반환
경로 표현식
- 상태 필드
- 단순한 엔티티의 직접적인 속성에 접근
- 경로 탐색의 끝
- 단일 값 연관 경로
- 나의 엔티티와 연관된 다른 단일 엔티티를 참조할 때 사용
- 단일 객체를 반환
- 일대일(One-to-One) 또는 다대일(Many-to-One) 관계를 표현
- 예시) [JPQL] select o.member from Order o
- member를 탐색하기 위해 묵시적인 내부 조인 발생
- SQL: select m.* from Orders o inner join Member m on o.member_id = m.id
- 컬렉션 값 연관 경로
- 하나의 엔티티와 연관된 여러 엔티티를 참조할 때 사용
- 일대다(One-to-Many) 또는 다대다(Many-to-Many) 관계를 표현
- 예시) [JPQL] select o.members from Order o
- 컬렉션 연관 경로의 경우 컬렉션이 반환되기 때문에 엔티티의 탐색이 불가능함 -> members.name 등으로 접근 불가능(List에 담겨있는 객체의 내부 필드에 바로 접근하지 못하는 것과 비슷한 개념)
페치 조인 fetch join
- JPQL에서 성능 최적화를 위해 사용되는 기법
- 기본적으로 엔티티와 그 연관된 엔티티를 함께 조회할 때 사용
- join fetch 명령어를 통해 사용 가능
- 예시) [JPQL] select m from Member m join fetch m.team
- [SQL] SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID=T.ID
- 지연 로딩으로 설정된 경우 일반 조인 사용 시 연관된 엔티티가 로드되지 않아 N+1 쿼리가 발생
- 페치 조인 사용 시 지연 로딩으로 설정되어도 관련 엔티티 즉시 로딩 가능
- 제한 사항
- 페치 조인을 사용할 때, 연관된 엔티티가 다수일 경우 중복 데이터가 발생할 수 있음
- 데이터베이스를 기준으로 결과를 반환하기 때문에 데이터베이스에 실제 반환되는 쿼리 수가 10개라면 동일한 결과의 코드가 10개가 반환됨 -> DISTINCT를 사용하여 중복 제거
- 페치 조인으로 인해 데이터가 예상보다 많아질 경우, 쿼리 성능이 저하될 수 있음
- 페치 조인 대상에는 별칭 지정 불가
- 컬렉션을 페치 조인 시 페이징 API 사용 불가
다형성 쿼리 TREAT
- 객체 지향 프로그래밍에서의 다형성을 활용하여 쿼리를 작성하는 기능
- 상속 구조를 가진 엔티티 클래스들 간의 관계를 쿼리 할 때 사용
- 예시) [JPQL] select i from Item i where treat(i as Book).author = ‘kim’
- [SQL] select i.* from Item i where i.DTYPE = ‘B’ and i.author = ‘kim
- 타입 캐스팅 하듯이 사용
벌크 연산
- 데이터베이스에 대해 대량의 데이터를 효율적으로 처리할 수 있는 쿼리 작업
- 주로 대량의 데이터 수정(UPDATE)이나 삭제(DELETE)를 한 번의 쿼리로 처리할 때 사용
- 특정 조건에 맞는 데이터를 한 번의 쿼리로 수정하는 방식
벌크 연산 주의점
- 영속성 컨텍스트 동기화 문제
- 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 실행
- 벌크 연산 실행 시 데이터베이스에 실제 업데이트가 이루어짐
- 데이터베이스의 값은 변경되었으나 영속성 컨텍스트의 값은 변경되지 않음
- 영속성 컨텍스트를 초기화하지 않을 시 1차 캐시에 저장된 정보를 반환
- 실제 데이터베이스의 정보와 일치하지 않음
- 해결법) 벌크 연산 후에는 영속성 컨텍스트를 초기화하거나, 벌크 연산 전에 플러시를 수행
- 엔티티 리스너와의 상호작용
- 벌크 연산은 엔티티 리스너(@PrePersist, @PostUpdate)와 같은 엔티티의 라이프사이클 콜백을 호출하지 않음
- 엔티티의 상태가 변경된 것을 감지하지 않아 관련된 로직이 필요하다면 수동으로 처리
자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런 (inflearn.com) 강의 내용 참고
728x90
'백엔드 > Spring' 카테고리의 다른 글
[Spring] JPA 지연 로딩 & 조회 성능 최적화 (0) | 2024.09.20 |
---|---|
[Spring] API (1) | 2024.09.19 |
[Spring] JPA 값 타입 (0) | 2024.09.12 |
[Spring] JPA 프록시 (0) | 2024.09.11 |
[Spring] 연관관계 매핑 (0) | 2024.09.10 |