Bersemangat / Malas Memuatkan Di Hibernate

Ketekunan atas

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

>> SEMAK KURSUS

1. Pengenalan

Semasa bekerja dengan ORM, pengambilan / pemuatan data dapat diklasifikasikan kepada dua jenis: bersemangat dan malas.

Dalam artikel ringkas ini kita akan menunjukkan perbezaan dan menunjukkan yang boleh digunakan dalam Hibernate.

2. Pergantungan Maven

Untuk menggunakan Hibernate, pertama-tama tentukan kebergantungan utama dalam pom.xml kami :

 org.hibernate hibernate-core 5.2.2.Final 

Versi terbaru Hibernate boleh didapati di sini.

3. Memuatkan Bersemangat dan Malas

Perkara pertama yang harus kita bincangkan di sini adalah apa yang memuatkan malas dan bersemangat memuat:

  • Eager Loading adalah corak reka bentuk di mana inisialisasi data berlaku di tempat
  • Lazy Loading adalah corak reka bentuk yang digunakan untuk menangguhkan inisialisasi objek selama mungkin

Mari lihat bagaimana ini benar-benar berfungsi 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 }

The OrderDetail kelas:

@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 boleh mempunyai banyak Perincian Pesanan . Dalam strategi memuat bersemangat, jika kita memuat data Pengguna , itu juga akan memuatkan semua pesanan yang terkait dengannya dan akan menyimpannya dalam memori .

Tetapi, apabila pemuatan malas diaktifkan, jika kita menggunakan UserLazy , data OrderDetail tidak akan diinisialisasi dan dimuat ke dalam memori sehingga panggilan eksplisit dibuat kepadanya.

Di bahagian seterusnya kita akan melihat bagaimana contoh di atas dilaksanakan di Hibernate.

4. Memuatkan Konfigurasi

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

Pemuatan Lazy hanya boleh diaktifkan menggunakan parameter penjelasan berikut:

fetch = FetchType.LAZY

Untuk menggunakan Eager Fetching parameter berikut digunakan:

fetch = FetchType.EAGER

Untuk menyediakan Eager Loading kita telah menggunakan UserLazy kelas twin 's dipanggil UserEager .

Pada bahagian seterusnya kita akan melihat perbezaan antara dua jenis pengambilan.

5. Perbezaan

Seperti yang telah kami sebutkan, perbezaan utama antara dua jenis pengambilan adalah saat data dimuat ke dalam memori.

Mari 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 apabila dipanggil secara eksplisit dengan menggunakan getter atau kaedah lain seperti yang ditunjukkan dalam contoh di atas:

UserLazy userLazyLoaded = users.get(3);

Tetapi dengan pendekatan yang bersemangat di UserEager, ia akan diinisialisasi dengan segera pada baris pertama contoh di atas:

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

Untuk malas memuatkan objek proksi digunakan dan pertanyaan SQL yang terpisah diaktifkan untuk memuatkan pesananDetailSet .

Idea untuk melumpuhkan proksi atau pemuatan malas dianggap sebagai amalan buruk di Hibernate. Ini dapat mengakibatkan banyak data diambil dari pangkalan data dan disimpan dalam memori, tanpa mengira kebutuhannya.

Kaedah berikut boleh digunakan untuk menguji fungsi di atas:

Hibernate.isInitialized(orderDetailSet);

Sekarang penting untuk melihat pertanyaan yang dihasilkan dalam kedua-dua kes:

true

Tetapan di atas dalam pengambilan.hbm.xml menunjukkan pertanyaan SQL yang dihasilkan. Sekiranya anda melihat output konsol, anda akan dapat melihat pertanyaan yang dihasilkan.

Untuk Malas Memuat pertanyaan yang dihasilkan untuk memuatkan data Pengguna :

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

Namun, semasa memuatkan dengan bersungguh-sungguh, kami melihat gabungan 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=?

Pertanyaan di atas dihasilkan untuk semua Pengguna , yang menghasilkan memori lebih banyak digunakan daripada pendekatan lain.

6. Kelebihan dan Kekurangan

6.1. Sedang Memuatkan

Kelebihan:

  • Masa muatan awal jauh lebih kecil daripada pendekatan lain
  • Penggunaan memori lebih sedikit daripada pendekatan lain

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 diperhatikan bahawa apabila persatuan tersebut diwakili sebagai kelas pengumpulan (dalam contoh di atas ia diwakili sebagai Set orderDetailSet ), maka pembungkus dibuat dan diganti dengan koleksi asli.

Untuk mengetahui lebih lanjut mengenai corak reka bentuk proksi, anda boleh merujuk di sini.

8. Kesimpulannya

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

Untuk kepakaran tahap lanjutan, anda boleh melihat laman web rasmi Hibernate. Untuk mendapatkan kod yang dibincangkan dalam artikel ini, sila lihat repositori ini.

Ketekunan bawah

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

>> SEMAK KURSUS