Life Developer
인생 개발자
[JPA]벌크연산

벌크연산 - 한방쿼리 - 영속성 컨텍스트 개무시하고 바로 DB에 쿼리 때림 

 

 

 

니 운동 좀 했는갑네.

몸이 벌크업됐노.

 

에서 벌크란 통? 이라고 할수가 있다. 통, 즉, 사이즈가 업됐노.

 

이렇게 생각할수 있는데.

 

벌크연산도 통연산 이라고 해석해도 될거같다.

 

통으로 연산 때리는 거다.

 

쿼리 한번으로 여러 테이블 로우 조져버리는거임.

 

update와 delete를 지원한다.

 

뭐 JPA 표준 스펙에는 없는데 하이버네이트가 지원하는것도 있다.

 

inset into ...select ~~ 이런거.

 

select해서 insert 조지는거...뭐 이런정도?

 

 

int resultCount = em.createQuery("update Member m set m.age=100").executeUpdate();
System.out.println("resultCount = " + resultCount);

 

em.createQuery에 update문 쌔리고 .executeUpdate 때리면 된다.

 

결과값은 변경된 컬럼수가 나옴.

 

========================================================================

 

벌크 연산은 영속성 컨텍스트를 무시해버리고 DB에 직접 쿼리 때린다.

잘못하면 망한다. 어떻게 하느냐? 

 

-벌크 연산 먼저 실행 (flush 자동으로 됨)

-벌크 연산 수행 후 영속성 컨텍스트를 초기화

 

하면 된다.

 

 

아래경우 나이가 모두 100으로 바뀌지 않고 출력이 된다.

 

왜냐면 자동 flush insert 다 때리고 clear를 안해줬으니 영속성 컨텍스트에는 값들이 남아있기 때문에.

 

 

Team team = new Team();
team.setName("teamA");
em.persist(team);

Team team1 = new Team();
team1.setName("teamB");
em.persist(team1);

Member member = new Member();
member.setUsername("userA");
member.setAge(10);
member.setType(MemberType.ADMIN);

Member member1 = new Member();
member1.setUsername("userB");
member1.setAge(70);
member1.setType(MemberType.USER);

Member member2 = new Member();
member2.setUsername("userC");
member2.setAge(90);
member2.setType(MemberType.USER);

member.setTeam(team);
member1.setTeam(team1);
member2.setTeam(team1);

em.persist(member);
em.persist(member1);
em.persist(member2);

//flush 자동 호출
int resultCount = em.createQuery("update Member m set m.age=100").executeUpdate();
System.out.println("resultCount = " + resultCount);

System.out.println("member1.getAge() = " + member.getAge());
System.out.println("member1.getAge() = " + member1.getAge());
System.out.println("member1.getAge() = " + member2.getAge());

System.out.println(" ======================================================= ");
tx.commit(); //이시점에 DB 쿼리가 날라감

 

 

 

그럼 이때는?

 

~

~

~

em.persist(member);
em.persist(member1);
em.persist(member2);


//flush 자동 호출
int resultCount = em.createQuery("update Member m set m.age=100").executeUpdate();
System.out.println("resultCount = " + resultCount);

Member mem = em.find(Member.class, member.getId());

System.out.println("mem = " + mem.getAge());

System.out.println(" ======================================================= ");
tx.commit(); //이시점에 DB 쿼리가 날라감

 

 

 

ㅋㅋ 이때도 mem.getAge 해봤자 100이 안나옴..

 

왜냐하면 벌크연산은 DB로 바로 쿼리를 쳐때려버리고 영속성 컨텍스트를 개무시하니까.

 

즉, 영속성 컨텍스트에 남아있는 em.persist(member); 이 놈을 불러옴.ㅋ....미띤

 

 

그래서 clear를 여기 써주면 새로가져온다

 

int resultCount = em.createQuery("update Member m set m.age=100").executeUpdate();
System.out.println("resultCount = " + resultCount);

em.clear();

Member mem = em.find(Member.class, member.getId());

'Developer' 카테고리의 다른 글

[JPA실전]lombok 다운  (0) 2020.09.28
[JPA실전]시작  (0) 2020.09.28
[JPA]JPQL-Named쿼리  (0) 2020.09.22
[JPA]쿼리에 Entity 직접 사용하기  (0) 2020.09.22
[JPA]다형성 JPQL 쿼리  (0) 2020.09.22
  Comments,     Trackbacks