일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Spring
- 스트리밍서버
- autowired
- db 스키마
- 이커머스 api
- SpringBoot
- 스프링
- 멀티쓰레드
- api설계
- Gradle
- 이커머스
- 인턴생활
- RDB
- 네이버
- 자바
- restful
- async
- 실검
- DB 설계
- REST API
- 서버구축
- cmi
- API
- mariaDB
- JPA
- AWS
- wooza
- @async
- 미디어서버
- 라이브커머스
Archives
- Today
- Total
Polymor!
[Spring] JPA 쿼리 분석 (1) 연관관계 정의 본문
1 : N (일대다) 연관 관계를 갖는 Cart와 CartItem을 상상하자.
1개의 Cart는 N개의 CartItem을 가질 수 있다. 양방향 연관관계 매핑을 아래와 같이 한다.
CascadeType.ALL은 영속성을 전이하는 것이다. Cart의 영속성이 연관관계를 갖는 CartItem list Entities에 전이되는 것 뿐이다.그러나 Cart가 CartItem의 변경감지를 대신해주진 않음 절대로.
// Cart Entity
@OneToMany(fetch = FetchType.LAZY,mappedBy="cart",cascade = CascadeType.ALL, orphanRemoval = true) // 02-15 Megan
private List<CartItem> cartItems;
// CartItem Entity
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cart_id")
* Cart가 가지고 있는 연관 엔티티 CartItem 들 중 하나의 quantity 값을 수정한다고 가정하자.
1. Cart 영속성 : 없음 -> CartItem 영속성 : 없음
( @Service logic에는 @transactional 없고, getCartItems()는 cart 엔티티 내부 메서드이다. != repo)
public void UpdateItemQuantity(long cartid,Integer quantity) {
Cart cart = this.findById(cartid);
cart.getCartItems().get(0).UpdateQuantity(quantity);
}
결과: Select 2회 (FetchType.Lazy로 설정했기때문에 getCartItems() 호출 시에 두번째 쿼리가 날라간다.)
Hibernate: select cart0_.cart_id as cart_id1_1_0_, cart0_.account_id as account20_1_0_, cart0_.address as address2_1_0_, cart0_.city as city3_1_0_, cart0_.content as content4_1_0_, cart0_.country as country5_1_0_, cart0_.created_at as created_6_1_0_, cart0_.grand_total as grand_to7_1_0_, cart0_.item_discount as item_dis8_1_0_, cart0_.item_price_total as item_pri9_1_0_, cart0_.province as provinc10_1_0_, cart0_.road_address as road_ad11_1_0_, cart0_.session_id as session12_1_0_, cart0_.shipping as shippin13_1_0_, cart0_.status as status14_1_0_, cart0_.tax as tax15_1_0_, cart0_.token as token16_1_0_, cart0_.updated_at as updated17_1_0_, cart0_.user_discount as user_di18_1_0_, cart0_.zip_code as zip_cod19_1_0_ from shop.cart cart0_ where cart0_.cart_id=?
Hibernate: select cartitems0_.cart_id as cart_id10_2_0_, cartitems0_.cart_item_id as cart_ite1_2_0_, cartitems0_.cart_item_id as cart_ite1_2_1_, cartitems0_.active as active2_2_1_, cartitems0_.cart_id as cart_id10_2_1_, cartitems0_.content as content3_2_1_, cartitems0_.created_at as created_4_2_1_, cartitems0_.discount_price as discount5_2_1_, cartitems0_.price as price6_2_1_, cartitems0_.product_id as product11_2_1_, cartitems0_.quantity as quantity7_2_1_, cartitems0_.sku as sku8_2_1_, cartitems0_.updated_at as updated_9_2_1_ from shop.cart_item cartitems0_ where cartitems0_.cart_id=?
2. Cart 영속성 : 저장 -> CartItem 영속성 : 저장
public void UpdateItemQuantity(long cartid,Integer quantity) {
Cart cart = this.findById(cartid);
cart.getCartItems().get(0).UpdateQuantity(quantity);
save(cart);
}
결과 : Select 2회 + update 1회 (Cart는 변경감지 없으므로 CartItem만 update 쿼리날림)
Hibernate: select cart0_.cart_id as cart_id1_1_0_, cart0_.account_id as account20_1_0_, cart0_.address as address2_1_0_, cart0_.city as city3_1_0_, cart0_.content as content4_1_0_, cart0_.country as country5_1_0_, cart0_.created_at as created_6_1_0_, cart0_.grand_total as grand_to7_1_0_, cart0_.item_discount as item_dis8_1_0_, cart0_.item_price_total as item_pri9_1_0_, cart0_.province as provinc10_1_0_, cart0_.road_address as road_ad11_1_0_, cart0_.session_id as session12_1_0_, cart0_.shipping as shippin13_1_0_, cart0_.status as status14_1_0_, cart0_.tax as tax15_1_0_, cart0_.token as token16_1_0_, cart0_.updated_at as updated17_1_0_, cart0_.user_discount as user_di18_1_0_, cart0_.zip_code as zip_cod19_1_0_ from shop.cart cart0_ where cart0_.cart_id=?
Hibernate: select cartitems0_.cart_id as cart_id10_2_0_, cartitems0_.cart_item_id as cart_ite1_2_0_, cartitems0_.cart_item_id as cart_ite1_2_1_, cartitems0_.active as active2_2_1_, cartitems0_.cart_id as cart_id10_2_1_, cartitems0_.content as content3_2_1_, cartitems0_.created_at as created_4_2_1_, cartitems0_.discount_price as discount5_2_1_, cartitems0_.price as price6_2_1_, cartitems0_.product_id as product11_2_1_, cartitems0_.quantity as quantity7_2_1_, cartitems0_.sku as sku8_2_1_, cartitems0_.updated_at as updated_9_2_1_ from shop.cart_item cartitems0_ where cartitems0_.cart_id=?
2021-03-11 11:42:33.445 INFO 1088 --- [ restartedMain] .d.s.w.r.o.CachingOperationNameGenerator : Generating unique operation named: findOrderIdUsingGET_1
Hibernate: update shop.cart_item set active=?, cart_id=?, content=?, created_at=?, discount_price=?, price=?, product_id=?, quantity=?, sku=?, updated_at=? where cart_item_id=?
3. Cart 영속성 : 변경감지로 인한 저장 -> CartItem 영속성 : 저장
@transactional
public void UpdateItemQuantity(long cartid,Integer quantity) {
Cart cart = this.findById(cartid);
cart.getCartItems().get(0).UpdateQuantity(quantity);
cart.updateItem(1000,10,10);
}
결과 : Select 2회 + update 2회
Hibernate: select cart0_.cart_id as cart_id1_1_0_, cart0_.account_id as account20_1_0_, cart0_.address as address2_1_0_, cart0_.city as city3_1_0_, cart0_.content as content4_1_0_, cart0_.country as country5_1_0_, cart0_.created_at as created_6_1_0_, cart0_.grand_total as grand_to7_1_0_, cart0_.item_discount as item_dis8_1_0_, cart0_.item_price_total as item_pri9_1_0_, cart0_.province as provinc10_1_0_, cart0_.road_address as road_ad11_1_0_, cart0_.session_id as session12_1_0_, cart0_.shipping as shippin13_1_0_, cart0_.status as status14_1_0_, cart0_.tax as tax15_1_0_, cart0_.token as token16_1_0_, cart0_.updated_at as updated17_1_0_, cart0_.user_discount as user_di18_1_0_, cart0_.zip_code as zip_cod19_1_0_ from shop.cart cart0_ where cart0_.cart_id=?
Hibernate: select cartitems0_.cart_id as cart_id10_2_0_, cartitems0_.cart_item_id as cart_ite1_2_0_, cartitems0_.cart_item_id as cart_ite1_2_1_, cartitems0_.active as active2_2_1_, cartitems0_.cart_id as cart_id10_2_1_, cartitems0_.content as content3_2_1_, cartitems0_.created_at as created_4_2_1_, cartitems0_.discount_price as discount5_2_1_, cartitems0_.price as price6_2_1_, cartitems0_.product_id as product11_2_1_, cartitems0_.quantity as quantity7_2_1_, cartitems0_.sku as sku8_2_1_, cartitems0_.updated_at as updated_9_2_1_ from shop.cart_item cartitems0_ where cartitems0_.cart_id=?
2021-03-11 11:42:33.445 INFO 1088 --- [ restartedMain] .d.s.w.r.o.CachingOperationNameGenerator : Generating unique operation named: findOrderIdUsingGET_1
Hibernate: update shop.cart set account_id=?, address=?, city=?, content=?, country=?, created_at=?, grand_total=?, item_discount=?, item_price_total=?, province=?, road_address=?, session_id=?, shipping=?, status=?, tax=?, token=?, updated_at=?, user_discount=?, zip_code=? where cart_id=?
Hibernate: update shop.cart_item set active=?, cart_id=?, content=?, created_at=?, discount_price=?, price=?, product_id=?, quantity=?, sku=?, updated_at=? where cart_item_id=?
(참고) FetchType.Lazy vs FetchType.Eager
# fetchType.LAZY - cartItem 정보 없음
Hibernate: select cart0_.cart_id as cart_id1_1_0_, cart0_.account_id as account20_1_0_, cart0_.address as address2_1_0_, cart0_.city as city3_1_0_, cart0_.content as content4_1_0_, cart0_.country as country5_1_0_, cart0_.created_at as created_6_1_0_, cart0_.grand_total as grand_to7_1_0_, cart0_.item_discount as item_dis8_1_0_, cart0_.item_price_total as item_pri9_1_0_, cart0_.province as provinc10_1_0_, cart0_.road_address as road_ad11_1_0_, cart0_.session_id as session12_1_0_, cart0_.shipping as shippin13_1_0_, cart0_.status as status14_1_0_, cart0_.tax as tax15_1_0_, cart0_.token as token16_1_0_, cart0_.updated_at as updated17_1_0_, cart0_.user_discount as user_di18_1_0_, cart0_.zip_code as zip_cod19_1_0_
from shop.cart cart0_
where cart0_.cart_id=?
#fetchType.EAGER - join 해서 다 가져옴
Hibernate: select cart0_.cart_id as cart_id1_1_0_, cart0_.account_id as account20_1_0_, cart0_.address as address2_1_0_, cart0_.city as city3_1_0_, cart0_.content as content4_1_0_, cart0_.country as country5_1_0_, cart0_.created_at as created_6_1_0_, cart0_.grand_total as grand_to7_1_0_, cart0_.item_discount as item_dis8_1_0_, cart0_.item_price_total as item_pri9_1_0_, cart0_.province as provinc10_1_0_, cart0_.road_address as road_ad11_1_0_, cart0_.session_id as session12_1_0_, cart0_.shipping as shippin13_1_0_, cart0_.status as status14_1_0_, cart0_.tax as tax15_1_0_, cart0_.token as token16_1_0_, cart0_.updated_at as updated17_1_0_, cart0_.user_discount as user_di18_1_0_, cart0_.zip_code as zip_cod19_1_0_, cartitems1_.cart_id as cart_id10_2_1_, cartitems1_.cart_item_id as cart_ite1_2_1_, cartitems1_.cart_item_id as cart_ite1_2_2_, cartitems1_.active as active2_2_2_, cartitems1_.cart_id as cart_id10_2_2_, cartitems1_.content as content3_2_2_, cartitems1_.created_at as created_4_2_2_, cartitems1_.discount_price as discount5_2_2_, cartitems1_.price as price6_2_2_, cartitems1_.product_id as product11_2_2_, cartitems1_.quantity as quantity7_2_2_, cartitems1_.sku as sku8_2_2_, cartitems1_.updated_at as updated_9_2_2_
from shop.cart cart0_
left outer join shop.cart_item cartitems1_ on cart0_.cart_id=cartitems1_.cart_id
where cart0_.cart_id=?
'Web' 카테고리의 다른 글
JPA , hibernate, 그리고 SpringDataApi (0) | 2021.02.24 |
---|---|
[네이버 라이브 쇼핑]스트리밍 서버 분석 1편 (0) | 2021.02.19 |
비동기에 대한 이해( feat. Spring @Async) (0) | 2021.02.12 |
[AWS] RDB 와 스프링 연동하기 (0) | 2021.02.10 |
[e-commerce] JPA 영속성 전이(feat.상품을 장바구니에 담기) (1) | 2021.02.07 |
Comments