Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- transaction
- java
- SpringBoot
- Greedy
- 김영한
- http
- Exception
- Servlet
- kotlin
- 스프링
- 그리디
- 백준
- Proxy
- 스프링 핵심 기능
- 자바
- spring
- springdatajpa
- db
- Spring Boot
- JPQL
- Android
- 인프런
- Thymeleaf
- JDBC
- QueryDSL
- 알고리즘
- 스프링 핵심 원리
- pointcut
- jpa
- AOP
Archives
- Today
- Total
개발자되기 프로젝트
Query Method, 벌크성 수정 쿼리 본문
예를들어 모든 인원의 나이를 하나 씩 올리거나, 연봉을 올리거나 할 때,
엔티티를 하나하나 불러와서 업데이트 하는 것 보다.
DB에서 bulk로 변경하는 편이 적합하다.
1. JPA로 bulk 연산
- executeUpdate()를 실행하면 업데이트, 삭데된 엔티티의 수를 반환.
public int bulkAgePlus(int age){
return em.createQuery("update Member m set m.age = m.age + 1 where m.age >= :age")
.setParameter("age", age)
.executeUpdate(); //Returns: the number of entities updated or deleted
}
public int bulkAgePlus(int age){
return em.createQuery("update Member m set m.age = m.age + 1 where m.age >= :age")
.setParameter("age", age)
.executeUpdate(); //Returns: the number of entities updated or deleted
}
2. SpringDataJpa에서 bulk 연산
- Query는 동일함
- @Modifying 적용 필요 : 해당 annotation이 적용되어야, jpa의 executeUpdate( )실행됨.
없으면 ResultRist or SingleResult 반환됨.
@Modifying //얘가 있어야 jpa의 .executeUpdate()실행됨. 없으면 resultRist or SingleResult 반환.
@Query("update Member m set m.age = m.age+1 where m.age >= :age")
int bulkAgePlug(@Param("age") int age);
@Test
public void bulkUpdate(){
//given
memberRepository.save(new Member("member1", 10));
memberRepository.save(new Member("member2", 19));
memberRepository.save(new Member("member3", 20));
memberRepository.save(new Member("member4", 21));
memberRepository.save(new Member("member5", 40));
//when
int resultCount = memberRepository.bulkAgePlug(20);
//then
Assertions.assertThat(resultCount).isEqualTo(3);
}
- @Modyfing을 빼면???
- InvalidDataAccessApiUsageException이 발생한다.
InvalidDataAccessApiUsageException: org.hibernate.hql.internal.QueryExecutionRequestException:
Not supported for DML operations
3. JPA의 BULK 연산 문제점
- JPA는 영속성 컨텍스트에서 엔티티를 관리한다.
- 하지만 BULK 연산을 하면 영속성 컨텍스트를 거치지 않고 바로 DB에 반영해버린다.
- 즉. BULK 연산 진행 후 영속성 컨텍스트와 DB에 DATA 차이가 있다.
- 다라서 BULK 연산 수 영속성 컨텍스트를 초기화 해야 한다.
- em.clear() -> 영속성 컨텍스트의 data 싹~ 날려버림.
@Test
public void bulkUpdate(){
//given
memberRepository.save(new Member("member1", 10));
memberRepository.save(new Member("member2", 19));
memberRepository.save(new Member("member3", 20));
memberRepository.save(new Member("member4", 21));
memberRepository.save(new Member("member5", 40));
//when
int resultCount = memberRepository.bulkAgePlug(20);
em.flush();
em.clear();
//then
Assertions.assertThat(resultCount).isEqualTo(3);
}
- 근데 springDataJPa에서 알아서 해줌ㅋㅋㅋㅋㅋㅋㅋ
- @Modifying(clearAutomatically = true)
@Modifying(clearAutomatically = true) //얘가 있어야 jpa의 .executeUpdate()실행됨. 없으면 resultRist or SingleResult 반환.
@Query("update Member m set m.age = m.age+1 where m.age >= :age")
int bulkAgePlug(@Param("age") int age);
@Test
public void bulkUpdate(){
//given
memberRepository.save(new Member("member1", 10));
memberRepository.save(new Member("member2", 19));
memberRepository.save(new Member("member3", 20));
memberRepository.save(new Member("member4", 21));
memberRepository.save(new Member("member5", 40));
//when
int resultCount = memberRepository.bulkAgePlug(20);
em.flush();
em.clear();
List<Member> result = memberRepository.findByUserName("member5");
Member member5 = result.get(0);
System.out.println("member5.getAge() = " + member5.getAge());
//then
Assertions.assertThat(resultCount).isEqualTo(3);
}
영속성 컨텍스트를 초기화 후 엔티티를 조회하므로 DB에 조회 쿼리가 날라감.
select
member0_.member_id as member_i1_0_,
member0_.age as age2_0_,
member0_.team_id as team_id4_0_,
member0_.user_name as user_nam3_0_
from
member member0_
where
member0_.user_name=?
member5.getAge() = 41
4. GitHub : 210829 SpringDataJpa Bulk
'인프런 > [인프런] Spring Data JPA' 카테고리의 다른 글
JPA Hint & Lock (0) | 2021.08.29 |
---|---|
@EntityGraph (0) | 2021.08.29 |
SpringDataJpa 페이징, 정렬 (0) | 2021.08.29 |
JPA의 페이징과 정렬 (0) | 2021.08.29 |
@Query, 반환 타입 (0) | 2021.08.29 |
Comments