Bersemangat / Malas Memuat Dalam mode Hibernasi

Ketekunan teratas

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya

1. Perkenalan

Saat bekerja dengan ORM, pengambilan / pemuatan data dapat diklasifikasikan menjadi dua jenis: eager dan lazy.

Dalam artikel singkat ini kami akan menunjukkan perbedaan dan menunjukkan bahwa perbedaan tersebut dapat digunakan dalam mode Hibernasi.

2. Ketergantungan Maven

Untuk menggunakan Hibernate, pertama-tama tentukan dependensi utama di pom.xml kami :

 org.hibernate hibernate-core 5.2.2.Final 

Versi terbaru Hibernate dapat ditemukan di sini.

3. Eager and Lazy Loading

Hal pertama yang harus kita bahas di sini adalah apa itu lazy loading dan eager loading:

  • Eager Loading adalah pola desain di mana inisialisasi data terjadi di tempat
  • Lazy Loading adalah pola desain yang digunakan untuk menunda inisialisasi objek selama memungkinkan

Mari kita lihat bagaimana sebenarnya ini bekerja dengan beberapa contoh:

The UserLazy kelas :

@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 = new HashSet(); // standard setters and getters // also override equals and hashcode }

Kelas 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 }

Satu Pengguna dapat memiliki beberapa OrderDetails . Dalam strategi eager loading, jika kita memuat data Pengguna , itu juga akan memuat semua pesanan yang terkait dengannya dan akan menyimpannya dalam memori .

Namun, saat pemuatan lambat diaktifkan, jika kita menarik UserLazy , data OrderDetail tidak akan diinisialisasi dan dimuat ke dalam memori sampai panggilan eksplisit dibuat untuk itu.

Pada bagian selanjutnya kita akan melihat bagaimana contoh di atas diimplementasikan dalam Hibernate.

4. Memuat Konfigurasi

Di bagian ini kita akan melihat bagaimana kita dapat mengkonfigurasi strategi pengambilan di Hibernate. Kami akan menggunakan kembali contoh dari bagian sebelumnya.

Lazy Loading dapat dengan mudah diaktifkan menggunakan parameter anotasi berikut:

fetch = FetchType.LAZY

Untuk menggunakan Eager Fetching, parameter berikut digunakan:

fetch = FetchType.EAGER

Untuk setup Memuat Bersemangat kita telah menggunakan UserLazy kelas kembar 's disebut UserEager .

Di bagian selanjutnya kita akan melihat perbedaan antara kedua jenis pengambilan.

5. Perbedaan

Seperti yang kami sebutkan, perbedaan utama antara kedua jenis pengambilan adalah momen ketika data dimuat ke dalam memori.

Mari kita lihat contoh ini:

List users = sessionLazy.createQuery("From UserLazy").list(); UserLazy userLazyLoaded = users.get(3); return (userLazyLoaded.getOrderDetail());

Dengan pendekatan inisialisasi malas, orderDetailSet akan diinisialisasi hanya jika dipanggil secara eksplisit menggunakan getter atau metode lain seperti yang ditunjukkan pada contoh di atas:

UserLazy userLazyLoaded = users.get(3);

Namun dengan eager approach di UserEager akan langsung diinisialisasi di baris pertama contoh di atas:

List user = sessionEager.createQuery("From UserEager").list();

Untuk pemuatan lambat, objek proxy digunakan dan kueri SQL terpisah dijalankan untuk memuat orderDetailSet .

Gagasan untuk menonaktifkan proxy atau pemuatan lambat dianggap sebagai praktik yang buruk di Hibernate. Ini bisa mengakibatkan banyak data diambil dari database dan disimpan dalam memori, terlepas dari kebutuhannya.

Metode berikut dapat digunakan untuk menguji fungsionalitas di atas:

Hibernate.isInitialized(orderDetailSet);

Sekarang penting untuk melihat kueri yang dihasilkan dalam kedua kasus:

true

Pengaturan di atas dalam fetching.hbm.xml menunjukkan kueri SQL yang dihasilkan. Jika Anda melihat keluaran konsol maka Anda akan dapat melihat kueri yang dihasilkan.

Untuk Lazy Loading query yang dihasilkan untuk memuat data User :

select user0_.USER_ID as USER_ID1_0_, ... from USER user0_

Namun, saat memuat dengan bersemangat, kami melihat ada gabungan yang dibuat dengan USER_ORDER:

select orderdetai0_.USER_ID as USER_ID4_0_0_, orderdetai0_.ORDER_ID as ORDER_ID1_1_0_, orderdetai0_ ... from USER_ORDER orderdetai0_ where orderdetai0_.USER_ID=?

Kueri di atas dibuat untuk semua Pengguna , yang menghasilkan lebih banyak memori yang digunakan daripada dalam pendekatan lainnya.

6. Keuntungan dan Kerugian

6.1. Pemuatan Lambat

Keuntungan:

  • Waktu muat awal jauh lebih kecil daripada pendekatan lainnya
  • Konsumsi memori lebih sedikit dibandingkan dengan pendekatan lainnya

Disadvantages:

  • Delayed initialization might impact performance during unwanted moments
  • In some cases you need to handle lazily-initialized objects with a special care or you might end up with an exception

6.2. Eager Loading:

Advantages:

  • No delayed initialization related performance impacts

Disadvantages:

  • Long initial loading time
  • Loading too much unnecessary data might impact performance

7. Lazy Loading in Hibernate

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation of classes.

Hibernate intercepts calls to an entity by substituting it with a proxy derived from an entity’s class. In our example, when a requested information is missing, it will be loaded from a database before control is ceded to the User class implementation.

Perlu juga dicatat bahwa ketika pengaitan direpresentasikan sebagai kelas koleksi (dalam contoh di atas direpresentasikan sebagai Set orderDetailSet ), maka pembungkus dibuat dan diganti untuk koleksi asli.

Untuk mengetahui lebih lanjut tentang pola desain proxy Anda dapat merujuk di sini.

8. Kesimpulan

Dalam artikel ini, kami menunjukkan contoh dari dua jenis pengambilan utama yang digunakan dalam Hibernate.

Untuk keahlian tingkat lanjut, Anda dapat melihat situs web resmi Hibernate. Untuk mendapatkan kode yang dibahas di artikel ini, silakan lihat di repositori ini.

Ketekunan bawah

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya