JPA/JPQL
-
벌크 연산JPA/JPQL 2023. 8. 9. 14:52
재고가 10개 미만인 모든 상품의 가격을 10% 상승 시키자는 가정이 있다고 하자. JPA의 update는 변경 감지 기능이 가장 좋다. 1. 재고가 10개 미만인 상품을 리스트로 조회 2. 상품 엔티티의 가격을 10% 증가 3. 트랜잭션 커밋 시점에 변경감지가 동작 하지만 이런 과정을 거치며 변경된 데이터가 100건이라면 100번의 UPDATE SQL이 실행되어야 하니까 효율적이지 않다. 하나를 변경할 때에는 변경 감지가 좋지만 한 번에 여러 건을 변경할 때에는 벌크 연산이 좋다. 벌크 연산 예제 쿼리 한 번으로 여러 테이블 로우를 변경한다. int resultCount = em.createQuery("update Member m set m.age = 20") .executeUpdate(); Syste..
-
Named 쿼리JPA/JPQL 2023. 8. 9. 14:37
Named 쿼리 - 정적 쿼리 미리 정의해서 이름을 부여해두고 사용하는 JPQL 어노테이션, XML에 정의가능 애플리케이션 로딩 시점에 초기화 후 재사용 애플리케이션 로딩 시점에 쿼리를 검증 선언 방법 @Entity @NamedQuery( name = "Member.findByUsername", query = "select m from Member m where m.username = :username" ) @Getter @Setter public class Member { @Id @GeneratedValue private Long id; private String username; private int age; @ManyToOne @JoinColumn(name = "TEAM_ID") private Te..
-
엔티티를 직접 사용하기JPA/JPQL 2023. 8. 9. 14:30
JQPL에서는 기본 SQL과 다르게 엔티티를 직접 넘길 수 있다. JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다. 엔티티 직접 사용 - 기본 키 값 [JPQL] select count(m.id) from Member m // 엔티티의 아이디를 사용 select count(m) from Member m // 엔티티를 직접 사용 [SQL] (JPQL 둘 다 같은 SQL로 실행됨) select count(m.id) as cnt from Member m 엔티티를 파라미터로 전달 String jpql = "select m from Member m where m = :member"; Member findMember = em.createQuery(jpql, Member.class..
-
페치 조인의 한계JPA/JPQL 2023. 8. 9. 14:17
1. 페치 조인의 대상에는 별칭을 줄 수가 없다. "select t from Team t join fetch t.members as m" 뒤에 'as m'처럼 별칭을 붙일 수가 없다. 페치 조인은 연관된 데이터들을 모두 가져오는 것이기 때문에 그 중에 몇 개의 데이터만 가져온다던지 하는 쿼리는 하지 않는다. 하이버네이트에서 지원하기는 하지만 가급적 사용하지 않도록 하자. 페치 조인은 연간된 데이터를 모두 가져오는 것인데, 10개중에 5개만 가져오게 된다면 잘못하면 데이터가 지워질 수도 있거나 나중에 영속성 컨텍스트에서 문제가 될 수도 있다. 꼭 필요한 경우에는 어쩌다 한 번 쓸 수는 있지만 되도록 사용하면 안된다. 2. 둘 이상의 컬렉션은 페치 조인을 할 수가 없다. 일대 다와 일대 다의 매칭이므로 일대..
-
페치 조인(fetch join)JPA/JPQL 2023. 8. 9. 13:53
페치 조인은 JPA에서 매우 중요한 개념이고 실무에서도 너무 중요하다고 한다. 페치 조인이란? SQL 조인의 종류가 아님 JPQL에서 성능 최적화를 위해 제공하는 기능 연관된 엔티티나 컬렉션을 SQL 한번에 함께 조회하는 기능 join fetch 명령어 사용 엔티티 페치 조인 - @ManyToONE에서의 페치 조인 회원을 조회하면서 연관된 팀도 함께 조회(SQL 한 번에) [JQPL에서의 페치 조인] 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 Team teamA = new Team(); teamA.setName("팀A"); em.pe..
-
경로 표현식JPA/JPQL 2023. 8. 9. 11:43
경로 표현식 : .(점)을 찍어 객체 그래프를 탐색하는 것 select m.username // 상태 필드 from Member m join m.team t // 단일 값 연관 필드 join m.orders o // 컬렉션 값 연관 필드 where t.name = '팀A' 경로 표현식 종류 - 상태 필드(state filed) : 단순히 값을 저장하기 위한 필드 - 연관 필드(association filed) : 연관관계를 위한 필드 단일 값 연관 필드 : @ManyToOne, @OneToOne, 매핑 대상이 엔티티 컬렉션 값 연관 필드 : @OneToMany, @ManyToMany, 매핑 대상이 컬렉션 경로 표현식 특징 1. 상태 필드 : 경로 탐색의 끝이며 탐색을 하지 않음 2. 단일 값 연관 경로 ..
-
조건식 (CASE)JPA/JPQL 2023. 7. 14. 00:35
기본 CASE 식 "select " + "case 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"; CASE 식을 만들어서 특정 조건일 때를 호출 할 수 있다. COALESCE: 하나씩 조회해서 null이 아니면 반환 NULLIF: 두 값이 같으면 null 반환, 다르면 첫번째 값 반환 사용자 이름이 없으면 이름 없는 회원을 반환 select coalesce(m...
-
서브 쿼리JPA/JPQL 2023. 7. 14. 00:21
서브 쿼리의 예제들 - 나이가 평균보다 많은 회원 select m from Member m where m.age > (select avg(m2.age) from Member m2) (상위에서 정의한 Member m을 가져오지 않고 m2를 새로 만들어야지 서브 쿼리 성능이 잘 나옴) - 한 건이라도 주문한 고객 select m from Member m where (select count(o) from Order o where m = o.member) > 0 (서브 쿼리를 할 때 위에서 사용한 m을 아래 서브 쿼리로 끌고오면 성능이 잘 안 나옴) 서브 쿼리 지원 함수 [NOT] EXISTS (subquery): 서브쿼리에 결과가 존재하면 참 {ALL | ANY | SOME} (subquery) ALL 모두 ..