본문 바로가기

Java/JPA

JPQL - Named 쿼리, 벌크연산

Named 쿼리 - 정적쿼리

미리 정의해서 이름을 부여해두고 사용하는 JPQL.
어노테이션이나 xml에 정의한다.

Spring Data JPA에서는 인터페이스 메소드 위에다가 바로 @Query 어노테이션으로 사용가능

-> 실무에서는 스프링데이터jpa써야겠죠?

Named 쿼리 장점:

애플리케이션 로딩 시점에 초기화 한 후 재사용,

애플리케이션 로딩시점에 쿼리 검증함..(쿼리 이상하면 QuerySyntaxException오류 발생)

캐시하고 있어서 코스트 절약

@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();

for (Member member : resultList) {
    System.out.println("member = " + member);

}

벌크연산 - 쿼리 한 번으로 여러 테이블 로우 변경(엔티티)

재고가 10개 미만인 모든 상품의 가격을 10%상승하려면?
JPA변경감지기능 사용시 UPDATE 쿼리가 100개... 이걸 벌크연산이 해결해줌

insert, update, delete를 지원한다.

주의할 점 : 벌크연산은 영속성 컨텍스트에 작업 아무것도 안하고 직접 DB작업함.

벌크 연산 수행 후 영속성 컨텍스트 초기화해야함.

영속성 컨텍스트가 이미 변수값을 가지고 있는 경우 : 값이 10살으로 되어 있는 경우))

(벌크로 20살 때렸는데, 영속성에는 10살 되어있음 -> 초기화(clear)한 후 다시 가져와야 함.(이때 flush안해도 자동으로 벌크쿼리 날리면 flush됨.)


int resultCount = em.createQuery("update Member m set m.age = 20")
        .executeUpdate();

em.clear();
Member findMember = em.find(Member.class, member1.getId());
System.out.println("findMember.getAge() = " + findMember.getAge());//20
System.out.println(member1.getAge());//기존에 영속성에 있는 변수 : 10