Eager/Lazy Loading In Hibernate
Following technologies being used:
- Spring Boot 2
- Maven
- Eclipse
1. Introduction
Khi làm việc với ORM chắc hẳn các bạn sẽ bắt gặp 2 loại eagerloading lazyloading. Ở bài viết này tôi sẽ trình bày về sự khác biệt giữa hai loại này.
2. Maven Dependencies
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.2.Final</version>
</dependency>
ở đây chúng ta sử dụng hibernate 5.
3. Eager and Lazy Loading
Eager Loading được thiết kế giúp cho việc khởi tạo đối tượng ngay lập tức.
Lazy Loading được thiết kế giúp cho việc trì hoãn việc khởi tạo đối tưởng miễn là có thể theo dõi ví dụ sau: class UserLazy
Lazy Loading được thiết kế giúp cho việc trì hoãn việc khởi tạo đối tưởng miễn là có thể theo dõi ví dụ sau: class UserLazy
@Entity
@Table(name = "USER")
public class UserLazy implements Serializable {
@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long userId;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<OrderDetail> orderDetail ;
// standard setters and getters
// also override equals and hashcode
}
class OrderDetail
@Entity
@Table (name = "USER_ORDER")
public class OrderDetail implements Serializable {
@Id
@GeneratedValue
@Column(name="ORDER_ID")
private Long orderId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="USER_ID")
private UserLazy user;
// standard setters and getters
// also override equals and hashcode
}
OrderDetail Annotation @OneToMany định nghĩa quan hệ giữa UserLazy và OrderDetail là 1-n.
Trong đó có thuộc tính fetch:
fetch = FetchType.LAZY tức là khi bạn find, select đối tượng UserLazy
từ database thì nó sẽ không lấy các đối tượng OrderDetail liên quan nếu bạn sử dụng:
fetch = FetchType.EAGER tức là khi bạn find, select đối tượng UserLazy từ database thì tất cả các đối tượng OrderDetail liên quan sẽ được lấy ra và lưu vào set orderDetail
Lưu ý
fetch = FetchType.LAZY tức là mặc định không lấy ra các đối tượng quan hệ dù trong cùng một transaction chỉ khi bạn gọi getOrderDetail() thì lúc này truy vấn lấy dữ liệu danh sách orderDetail sẽ được thực hiện.
Nếu bạn không gọi getOrderDetail() thì list này sẽ không có dữ liệu và kết thúc transaction sẽ không có danh sách orderDetail nào cả =))
fetch = FetchType.EAGER thì khi lấy đối tượng UserLazy là nó mặc định query luôn các đối tượng OrderDetail liên quan và lưu vào set orderDetail, do đó khi kết thúc transaction, set orderDetail sẽ có chứa các đối tượng UserLazy của OrderDetail đó.
Trong đó có thuộc tính fetch:
fetch = FetchType.LAZY tức là khi bạn find, select đối tượng UserLazy
từ database thì nó sẽ không lấy các đối tượng OrderDetail liên quan nếu bạn sử dụng:
fetch = FetchType.EAGER tức là khi bạn find, select đối tượng UserLazy từ database thì tất cả các đối tượng OrderDetail liên quan sẽ được lấy ra và lưu vào set orderDetail
Lưu ý
fetch = FetchType.LAZY tức là mặc định không lấy ra các đối tượng quan hệ dù trong cùng một transaction chỉ khi bạn gọi getOrderDetail() thì lúc này truy vấn lấy dữ liệu danh sách orderDetail sẽ được thực hiện.
Nếu bạn không gọi getOrderDetail() thì list này sẽ không có dữ liệu và kết thúc transaction sẽ không có danh sách orderDetail nào cả =))
fetch = FetchType.EAGER thì khi lấy đối tượng UserLazy là nó mặc định query luôn các đối tượng OrderDetail liên quan và lưu vào set orderDetail, do đó khi kết thúc transaction, set orderDetail sẽ có chứa các đối tượng UserLazy của OrderDetail đó.
4 FetchType mặc định
Mặc đinh:
annotation @ManyToOne và @OneToOne thì fetchType EAGER là mặc định
annotation @ManyToMany và @OneToMany thì fetchType LAZY là mặc định
annotation @ManyToOne và @OneToOne thì fetchType EAGER là mặc định
annotation @ManyToMany và @OneToMany thì fetchType LAZY là mặc định
5. So sánh
Với FetchType = LAZY(Lazy Loading):
Ưu điểm:
- Tiết kiệm thời gian
- Tiết kiệm bộ nhớ Nhược điểm:
- gây ra lỗi LazyInitializationException, khi muốn lấy các đối tượng liên quan phải mở transaction 1 lần nữa để query hay còn gọi là n+1 query
Với FetchType = EAGER(Eager Loading):
Ưu điểm:
- Lấy trực tiếp các đối tượng liên quan
- Xử lý đơn giản Nhược điểm:
- Tốn nhiều thời gian và bộ nhớ khi truy vấn select
- Dữ liệu lấy ra bị thừa nếu không dùng tới.
- Nhận đường liên kết
- X
- Ứng dụng khác
Nhãn
Java
Nhãn:
Java
- Nhận đường liên kết
- X
- Ứng dụng khác
Nhận xét
Đăng nhận xét