우주먼지

💡 벌크 연산

  • PK를 특정한 엔티티의 Update, Delete를 제외한 모든 Update, Delete 쿼리이다.
  • 쿼리 한 번으로 여러 테이블의 Row를 변경한다. (Entity)
  • executeUpdate()의 결과는 영향을 받은 Entity의 수를 반환한다.
  • Insert 문을 Hibernate에서 지원한다. (insert into .. select)
// 재고가 10개 미만인 Product의 Price를 쿼리 한 번으로 10% 인상
String qlString = 
    "update Product p " +
    "set p.price = p.price * 1.1 " +
    "where p.stockAmount < :stockAmount";

int resultCount = em.createQuery(qlString)
    .setParameter("stockAmount", 10)
    .executeUpdate();

 

주의점

벌크연산은 영속성 컨텍스트를 무시하고 DB에 직접 쿼리한다. (데이터 정합성)

 

2가지 해결 방법

  • 벌크 연산을 먼저 실행
  • 벌크 연산 실행 후 영속성 컨텍스트 초기화 (em.clear())

💡 다형성 쿼리

 

Type

조회 대상을 특정 하위 클래스로 한정할 수 있다.

예를 들어서 Item이 상위클래스이고 Book, Movie, Song 등 하위 클래스들이 있다고 가정한다.

Item의 하위 클래스 중 Book, Movie만 조회해보자.

String query = "select i from Item i where type(i) in (Book, Movie)";

 

Treat (JPA 2.1)

  • 자바의 타입 캐스팅과 유사하다.
  • 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용한다.
  • FROM, WHERE, SELECT(Hibernate 지원)를 사용한다.

 

부모 타입의 다운캐스팅 예시

String query = "select i from Item i where treat(i as Book).auther = 'Kim'";

💡 Named 쿼리 - 정적 쿼리

  • 엔티티 클래스에 미리 정의해서 이름을 부여해두고 사용하는 JPQL
  • 쿼리에 이름을 부여하며, 이름을 통해 쿼리를 불러오기가 가능하다.
  • 어노테이션, XML에 정의 (XML이 항상 우선권을 가진다.)
  • 어플리케이션 로딩 시점에 초기화 후 재사용 (SQL 로 파싱하여 쿼리를 캐싱함)
  • 어플리케이션 로딩 시점에 쿼리를 검증 - 컴파일 타임 시 에러 발생으로 인해 디버깅 용이
  • 보통 엔티티에 @NamedQuery보단 @Query가 사용하기 더 편하고 좋다.
// 엔티티 클래스에 정의
@Entity
@NamedQuery(
   name = "Member.findByUsername",
   query = "select m from Member m where m.username = :username")
public class Member {
...
}

// 사용
List<Member> resultList =
   em.createNamedQuery("Member.findByUsername", Member.class)
      .setParameter("username", "회원1")
      .getResultList();

// 이름 없는 Named Query
public interface MemberRepository extends JPARepository<Member, Long> {
    @Query("select m from Member m where m.address = ?1")
    Member findByAddress(String address);
}

💡 엔티티 직접 사용

JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다.

엔티티를 직접 사용하거나 파라미터로 넘겨도 동일하게 PK로 조회한다.

# 엔티티의 아이디를 사용
select count(m.id) from Member m

# 엔티티를 직접 사용
select count(m) from Member m

# 엔티티를 파라미터로 전달
select m from Member m where m = :member

# 식별자를 직접 전달
select m from Member m where m.id = :memberId

'Database > JPQL' 카테고리의 다른 글

JPQL Fetch Join  (0) 2023.03.19
JQPL 경로표현식  (2) 2023.03.19
JPQL Type Query & Sub Query  (0) 2023.03.11
JPQL Paging API & Search Result API  (0) 2023.03.11
JPQL Projection  (0) 2023.03.11
profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그