update2
Update
- JPA에서 값을 데이터베이스와 영속시키기 위한 몇가지 방법이 있다.
- 그중 하나가 merge 방법이다
- merge 방법
- findbyid로 값을 가져온 뒤 영속을 시켜둔 상태에서 필요시마다 save 메소드를 날리면서 id값 기준으로 동일한 값이 있는지 체킹하고
- update가 없다면 insert를 날려주는 방식이다.
- 하지만 이러한 방법은 매번 쿼리를 날릴 때마다 select insert / select update를 날리게 된다
- 이것은 불필요한 데이터 베이스 체킹이 한번씩 날라가는 것이다.
- 이러한 것을 방지하기 위한것이 더티체킹이다
- 더티체킹
- 디비에 왔다 갔다 하는 방법을 맨 처음 영속할 때 한 번, 그리고 모든 프로세스가 종료될 때 한번 이렇게 두 번만 하는 것이다.
- 이것을 위해서는 해당 메서드에 @Transactional 어노테이션으로 묶어줘야 한다
- 그러면 jpa는 1차 캐싱 부분에 값을 계속 저장하고 변경하면서 마지막 commit 시점에 flush를 날려준다고 생각하면 된다
- 만약 엔티티의 컬럼이 너무 많을 경우에는 update를 필요하고 변경된 부분만 날릴 수 있는데 이 방법은 entity class에 @DynamicUpdate라는 어노테이션을 추가해주면 된다.
1
2
3
4
5
6
public String testJpa(String id){
Optional<TestTable> enttList = repo.findById(id);
TestTable dto = enttList.get();
dto.setFctr1("40");
System.out.println("++++++++");
}
- 위의 함수를 테스트 해보자
- 현재 코드 그대로 테스트
- 현재 코드에서 @Transactional 어노테이션만 추가 후 테스트
- 현재코드에서 System 출력 이전과 이후에 각각 repository.save(dto); 코드를 추가해서 save 함수 집어넣기
- 결과
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
31
32
33
34
35
36
37
38
39
40
41
42
43
public String testJpa(String id){
Optional<TestTable> enttList = repo.findById(id);
TestTable entity = enttList.get();
entity.setFctr1("40");
System.out.println("++++++++");
}
// ++++++++ 만 출력. 코드 update 안됨
// save 저장도 없고 Transactional로 묶이지 않아 아무리 엔티티가 변했다해도 쿼리가 날아가지 않고 종료된다
@Transactional
public String testJpa(String id){
Optional<TestTable> enttList = repo.findById(id);
TestTable entity = enttList.get();
entity.setFctr1("40");
System.out.println("++++++++");
}
// ++++++++ 후 update query 전송.
// Transactional로 묶여 있기 때문에 묶인 메서드가 종료될 때 commit이 일어나기 때문에 종료 직전 ++++를 찍고 update가 이뤄진다
public String testJpa(String id){
Optional<TestTable> enttList = repo.findById(id);
TestTable entity = enttList.get();
entity.setFctr1("40");
repository.save(entity);
System.out.println("++++++++");
}
// update query 전송 후 ++++ 출력
public String testJpa(String id){
Optional<TestTable> enttList = repo.findById(id);
TestTable entity = enttList.get();
entity.setFctr1("40");
System.out.println("++++++++");
repository.save(entity);
}
// ++++ 출력 후 update query 전송
// 3번과 4번의 경우 일단 entity는 setter를 쓰는 것을 지양한다. 하지만 편의상 했다.
// Transactional 로 묶여있지는 않지만 실제로 commit을 위한 쿼리를 날리는 save 함수를 직접 호출했기에 결과가 위와 같다