728x90
반응형
재고가 10개 미만인 모든 상품의 가격을 10% 올리려면 어떻게 해야할까?
JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL이 실행되어야 한다.
(1) 재고가 10개 미만인 상품을 리스트로 조회한다.
(2) 상품 엔티티의 가격을 10% 증가한다
(3) 트랜잭션 커밋 시점에 변경감지가 동작한다.
변경된 데이터가 100건이라면 100번의 UPDATE SQL이 실행될 것이다.
벌크 연산은 쿼리 한 번으로 여러 테이블 로우를 변경한다(엔티티)
executeUpdate()의 결과는 영향받은 엔티티의 수를 반환하는데, UPDATE, DELETE 쿼리를 지원한다
INSERT(insert into .. select, 하이버네이트 지원)
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();
벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리한다.
벌크 연산을 먼저 실행하고,
벌크 연산 수행 후 영속성 컨텍스트를 초기화해야 한다.
Team teamA = new Team();
teamA.setName("teamA");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("teamB");
em.persist(teamB);
Member member = new Member();
member.setUsername("회원1");
member.setAge(0);
member.setTeam(teamA);
member.setType(MemberType.ADMIN);
em.persist(member);
Member member2 = new Member();
member2.setUsername("회원2");
member2.setAge(0);
member2.setTeam(teamA);
member2.setType(MemberType.USER);
em.persist(member2);
Member member3 = new Member();
member3.setUsername("회원3");
member3.setAge(0);
member3.setTeam(teamB);
member3.setType(MemberType.USER);
em.persist(member3);
// FLUSH 자동 호출
int resultCount = em.createQuery("update Member m set m.age = 20")
.executeUpdate();
em.clear(); /// 영속성 컨텍스트를 초기화해줘야 한다. 그렇지 않으면 DB에만 저장되고, 1차 캐시에는 저장되지 않는다.
Member findMember = em.find(Member.class, member.getId());
System.out.println("findMember = " + findMember.getAge());
System.out.println("resultCount = " + resultCount);
em.clear(); 까지 해줘야, 영속성 컨텍스트까지 초기화 되어야 데이터를 메모리에서도 가져와서 사용할 수 있다.
728x90
반응형
'자바 > JPA' 카테고리의 다른 글
[JPA/Java] JPQL Named 쿼리 - 어노테이션, XML (0) | 2023.05.11 |
---|---|
[JPA/Java] JPQL 엔티티 직접 사용 (0) | 2023.05.11 |
[JPA/Java] JPQL 다형성 쿼리 - TYPE, TREAT (0) | 2023.05.11 |
[JPA/Java] JPQL 패치 조인의 한계 - 글로벌 배치 패치 사이즈, @BatchSize (0) | 2023.05.11 |
[JPA/Java] JPQL fetch join (패치 조인) (2) | 2023.05.10 |
댓글