벌크연산 - 한방쿼리 - 영속성 컨텍스트 개무시하고 바로 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 |