์ผ๋๋ค ๊ด๊ณ์ธ ์ปฌ๋ ์ ์ ํ์น ์กฐ์ธ์ผ๋ก ์กฐํํ ๋,
ํ๋์ ์ ๋ณด์ ์ฌ๋ฌ๊ฐ์ ์ปฌ๋ ์ ์ด ์๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๊ฐ ๋์ด๋๊ธฐ ๋๋ฌธ์ ์ต์ ํ์ ์ด๋ ค์์ด ์๋ค.
๋๋ฌธ์ ํ์ด๋ฒ๋ค์ดํธ ์ต์ ์ ์ค์ผ๋ก์จ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
์ํฐํฐ ์ง์ ๋ ธ์ถ
@GetMapping("/api/v1/orders")
public List<Order> ordersV1() {
List<Order> all = orderRepository.findAllByString(new OrderSearch());
for (Order order : all) {
order.getMember().getName(); //Lazy ๊ฐ์ ์ด๊ธฐํ
order.getDelivery().getAddress(); //Lazy ๊ฐ์ ์ด๊ธฐํ
List<OrderItem> orderItems = order.getOrderItems();
orderItems.stream().forEach(o -> o.getItem().getName()); //Lazy ๊ฐ์
์ด๊ธฐํ
}
return all;
}
LAZY๋ก๋ฉ์ด ๋์ด์๋ ํ๋ก์๋ฅผ ๊ฐ์ ์ด๊ธฐํ์์ผ์ฃผ์ด์ผํ๋ค.
ํ์ง๋ง ์ด ๋ฐฉ๋ฒ์ ์ํฐํฐ๋ฅผ ์ง์ ๋ ธ์ถ์ํค๊ธฐ ๋๋ฌธ์ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๋ค.
์ํฐํฐ๋ฅผ DTO๋ก ๋ณํ
public List<OrderDto> ordersV2() {
List<Order> orders = orderRepository.findAll();
List<OrderDto> result = orders.stream()
.map(o -> new OrderDto(o))
.collect(toList());
return result;
}
Order ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ ๋ค OrderDto ๋ก ๋ณํ์ํจ๋ค.์ํฐํฐ์ ๋ํ ์์กด์ ์์ ํ ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋จ์ํ Order์ ๋ํ ์ ๋ณด๋ง์ด ์๋, Item์ ๋ํ ์ ๋ณด๋ Dto๋ก ๋ณํ์ํจ๋ค.
static class OrderItemDto {
private String itemName;//์ํ ๋ช
private int orderPrice; //์ฃผ๋ฌธ ๊ฐ๊ฒฉ
private int count;
//์ฃผ๋ฌธ ์๋
public OrderItemDto(OrderItem orderItem) {
itemName = orderItem.getItem().getName();
orderPrice = orderItem.getOrderPrice();
count = orderItem.getCount();
}
}
ํ์ง๋ง ์ด๋ ๊ฒ ๋๋ฉด ์ฌ๋ฌ ๊ฐ์ ์ฌ๋ฌ ๋ฒ์ ์ง์ฐ๋ก๋ฉ์ด ๋ฐ์ํ ๋๋ง๋ค ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ 1+N ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
EX) ์ฃผ๋ฌธ 1๊ฐ , ์ฃผ๋ฌธ ์ ๋ณด N๊ฐ , ์ฃผ๋ฌธ ์ํ M๊ฐ ->1 + N + M ๋ฒ์ ์ฟผ๋ฆฌ ๋ฐ์
์ํฐํฐ๋ฅผ DTO๋ก ๋ณํ- ํจ์น ์กฐ์ธ ์ต์ ํ
public List<Order> findAllWithItem() {
return em.createQuery(
"select distinct o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d" +
" join fetch o.orderItems oi" +
" join fetch oi.item i", Order.class)
.getResultList();
}
์ด์ฒ๋ผ ํ์น ์กฐ์ธ์ ํตํด ์ต์ ํ๋ฅผ ํด์ฃผ๋ฉด , ์ฟผ๋ฆฌ๊ฐ ํ๋ฒ๋ง ์คํ๋จ์ผ๋ก์จ ๊ธฐ์กด 1+N ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
JPA ์ฟผ๋ฆฌ๋ฌธ์ distinct ๋ ๋ ๊ฐ์ง ๊ธฐ๋ฅ์ ํ๋ค.
1. SQL ์ distinct ์ถ๊ฐ
2. ๊ฐ์ ์ํฐํฐ ์ค๋ณต ์ ๊ฑฐ
ํ์ง๋ง , ์ด ์ฝ๋์์ ํ์ด์ง์ ํ๊ฒ ๋๋ฉด DB๊ฐ ์๋ ๋ฉ๋ชจ๋ฆฌ์์ ํ์ด์ง์ ํด๋ฒ๋ฆฐ๋ค.
์ด๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ(out of memory)๋ฅผ ์ผ์ผํฌ ์ ์๋ ๋งค์ฐ ์ํํ ํ์์์ผ๋ก ํ์ง ์๋ ๊ฒ์ด ์ข๋ค.
* ์ปฌ๋ ์ ํ์น ์กฐ์ธ์ 1๊ฐ๋ง ์ฌ์ฉํ ์ ์๋ค. ๋ ์ด์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ๋ถ์ ํฉ ๋ฐ์
์ํฐํฐ๋ฅผ DTO๋ก ๋ณํ- ํ์ด์ง ์ ์ฉ
์์ ์ฝ๋์์ ํ์ด์ง์ด ์๋๋ ์ด์ ๋ ์ผ๋๋ค ์กฐ์ธ์์ ๋ฐ์ดํฐ๊ฐ ์์ธกํ ์ ์์ด ์ฆ๊ฐ(N)ํ๊ธฐ ๋๋ฌธ์ด๋ค.ํ์ง๋ง ์ฌ๊ธฐ์ ํ์ด์ง์ ํ๊ฒ๋๋ฉด ํ์ด์ง ๊ธฐ์ค์ด N ์ ๋ง์ถ์ด์ง๋ค.
๋ฐ๋ผ์ JPA๋ ์ด ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ๋๋ฐ ์ด๊ฒ์ ๋งค์ฐ ์ํํ๋ค !
์ผ๋๋ค ๊ด๊ณ์์ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋๋ค.
1. ToOne ๊ด๊ณ๋ ROW ์๋ฅผ ์ฆ๊ฐ์ํค์ง ์์ผ๋ฏ๋ก ํ์น ์กฐ์ธ์ ํ๋ค.
2. ์ปฌ๋ ์ ์ ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ค์ ํ๋ค.
3. hibernate.default_batch_fetch_size , @BatchSize ๋ฅผ ์ ์ฉํ๋ค. (DB์์ ๋ฏธ๋ฆฌ ๋ถ๋ฌ์ฌ ๋ฐ์ดํฐ ์)
public List<Order> findAllWithMemberDelivery(int offset, int limit) {
return em.createQuery("select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class)
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList();
}
spring:
jpa:
properties:
hibernate:
default_batch_fetch_size: 1000
ToOne ๊ด๊ณ๋ฅผ ํ๋ฐฉ์ฟผ๋ฆฌ๋ก ๊ฐ์ ธ์ค๊ณ , default_batch_fetch_size ๋ฅผ ์ค์ ํด์ฃผ๋ฉด, ์ค์ ํ ์ฌ์ด์ฆ๋งํผ ์ปฌ๋ ์ ์ in ์ฟผ๋ฆฌ์ ๋ด์์ ๋ฐํํ๋ค.
๋ฐ๋ผ์ ๊ธฐ์กด 1+ N ์ด์๋ ์ฟผ๋ฆฌ ์๊ฐ 1+1 ๋ก ์ค์ด๋ ๋ค.
์ฌ์ค ToOne ๊ด๊ณ๋ ๊ตณ์ด ํ์น ์กฐ์ธ ์ํด๋ ์๊ด ์๋๋ฐ ์ด๋ ๊ฒ ํ๋ฉด ์ฟผ๋ฆฌ๋ฅผ ์ค์ผ ์ ์๋ค.
๋ง์ฝ ์กฐํ ํ ๋ฐ์ดํฐ ์๊ฐ 2๊ฐ์ด๊ณ ์ฌ์ด์ฆ๋ฅผ 1๋ก ์ค์ ํ์ผ๋ฉด , ์ฟผ๋ฆฌ๊ฐ ๋๋ฒ ์คํ๋๋ค. (1 X 2)
๋ง์ฝ ์กฐํ ํ ๋ฐ์ดํฐ ์๊ฐ 100๊ฐ์ด๊ณ ์ฌ์ด์ฆ๋ฅผ 10์ผ๋ก ์ค์ ํ์ผ๋ฉด , ์ฟผ๋ฆฌ๊ฐ ์ด๋ฒ ์คํ๋๋ค. (10 X 10)
์ด ๋ฐฉ๋ฒ์ ํ์น ์กฐ์ธ์ผ๋ก ํ์ ๋ ๋ณด๋ค ์ฟผ๋ฆฌ๋ ์ฝ๊ฐ ๋ง์ด ๋ฐ์ํ์์ง๋ ๋ชฐ๋ผ๋ ๋ฐ์ดํฐ ์ต์ ํ๊ฐ ๋์ด์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ๋ ์ข๋ค.
ํ์ง๋ง ์๊ท๋ชจ ๋ฐ์ดํฐ์ผ ๊ฒฝ์ฐ ํ์น ์กฐ์ธ์ผ๋ก ํ๋ ๊ฒ ๋ ๋น ๋ฅผ ์ ์๋ค (์ํฉ by ์ํฉ)
'jpa' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[jpa] OSIV ์ฑ๋ฅ ์ต์ ํ (0) | 2023.03.05 |
---|---|
[jpa] ์ปฌ๋ ์ ์กฐํ ์ต์ ํ - 2 (0) | 2023.03.01 |
[jpa] ์ง์ฐ๋ก๋ฉ๊ณผ ์กฐํ ์ฑ๋ฅ ์ต์ ํ (0) | 2023.02.25 |
[jpa] ๋ค์ํ ์ฐ๊ด๊ด๊ณ ๋งตํ ์ ๋ฆฌ (0) | 2023.02.19 |
์์๊ด๊ณ ๋งคํ ์ ๋ต ์ข ๋ฅ ๋ฐ ์ ํ๊ฐ์ด๋ (0) | 2022.02.27 |