Cache sesi disimpan dengan grafik objek yang saling terkait. Secara default, ketika Hibernate memuat objek pelanggan dari database, semua objek pesanan terkait dimuat pada saat yang sama. Mengambil kelas pelanggan dan pesanan sebagai contoh, asumsikan bahwa kunci asing customer_id dari tabel pesanan diizinkan menjadi nol
Metode Session的find() berikut digunakan untuk mengambil semua objek pelanggan dalam database:
List customerLists=session.find("from Customer as c");
Saat menjalankan metode find() di atas, Hibernate pertama -tama akan meminta semua catatan di tabel pelanggan, dan kemudian meminta tabel pesanan dengan hubungan referensi berdasarkan ID dari setiap catatan. Hibernate akan menjalankan pernyataan pilih berikut secara bergantian:
Pilih * dari pelanggan;
Pilih * dari pesanan di mana customer_id = 1;
Pilih * dari pesanan di mana customer_id = 2;
Pilih * dari pesanan di mana customer_id = 3;
Pilih * dari pesanan di mana customer_id = 4;
Melalui 5 pernyataan pilih di atas, Hibernate akhirnya memuat 4 objek pelanggan dan 5 objek pesanan, membentuk grafik objek terkait dalam memori.
Hibernate menggunakan kebijakan pencarian default sekarang saat mengambil objek pesanan yang terkait dengan pelanggan. Ada dua kekurangan utama dalam strategi pencarian ini:
(1) Jumlah pernyataan terpilih terlalu besar dan akses yang sering ke database akan mempengaruhi kinerja pengambilan. Jika Anda perlu meminta objek pelanggan, maka N+1 Pilih Pernyataan Kueri harus dieksekusi. Ini adalah masalah kueri klasik N+1 Select. Strategi pencarian ini tidak menggunakan fungsi kueri koneksi SQL. Misalnya, 5 pernyataan terpilih di atas dapat sepenuhnya diselesaikan dengan 1 pernyataan pilih berikut:
Pilih * dari pelanggan meninggalkan pesanan gabungan luar
di customers.id = orders.customer_id
Pernyataan SELECT di atas menggunakan fungsi kueri gabungan luar kiri SQL, yang dapat menanyakan semua catatan tabel pelanggan dan catatan tabel pesanan yang cocok dalam pernyataan SELECT.
(2) Dalam situasi di mana logika aplikasi hanya perlu mengakses objek pelanggan tetapi tidak memesan objek, memuat objek pesanan sama sekali tidak perlu. Objek urutan yang tidak perlu ini membuang banyak ruang memori.
Untuk menyelesaikan masalah di atas, Hibernate menyediakan dua strategi pencarian lainnya: strategi pencarian yang tertunda dan strategi pencarian koneksi yang mendesak. Strategi pengambilan yang tertunda dapat menghindari pemuatan yang berlebihan dari objek terkait yang tidak perlu diakses oleh aplikasi. Strategi pengambilan koneksi luar kiri yang mendesak memanfaatkan fungsi kueri koneksi luar SQL secara penuh dan dapat mengurangi jumlah pernyataan terpilih.
Masalah kinerja harus dipertimbangkan saat mengakses database. Setelah menetapkan hubungan 1-ke-banyak, masalah n +1 legendaris akan terjadi dalam kueri.
1) 1 hingga banyak, dalam 1 persegi, n objek dapat ditemukan, kemudian set yang terkait dengan N objek perlu dikeluarkan, sehingga kueri SQL asli menjadi N +1
2) banyak hingga 1. Jika Anda menanyakan objek M di banyak pihak, maka objek 1 partai yang sesuai dengan objek M akan dikeluarkan, dan itu juga akan menjadi M+1.
1) malas = true, hibernate3 telah default menjadi malas = true; Saat malas = benar, objek yang terkait tidak akan segera ditanya. Tindakan kueri hanya akan terjadi ketika objek terkait (mengakses atributnya, bidang non-ID).
2) Cache Level 2. Ketika objek jauh lebih sedikit diperbarui, dihapus, dan ditambahkan daripada kueri, penerapan cache Level 2 tidak akan takut akan masalah N +1, karena bahkan jika kueri pertama lambat, hit cache akan sangat cepat setelah itu.
Solusi yang berbeda dan ide yang berbeda, tetapi yang kedua kebetulan menggunakan N +1 lagi.
3) Tentu saja Anda juga dapat mengatur fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))
Di atas adalah semua tentang diskusi singkat artikel ini tentang edisi Hibernate n+1, dan saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!