cache
Hari ini kita akan berbicara tentang keadaan entitas dan cache hibernasi di Hibernate.
1) Pertama, mari kita lihat status entitas:
Ada tiga jenis utama entitas entitas: sementara, gigih, dan terpisah.
Anda mungkin memahaminya dengan membaca bahasa Inggris.
Transient: Mengacu pada data yang belum sesuai dengan data dalam database.
Persisten: Mengacu pada data yang sesuai dengan data dalam database, dan setiap perubahan di dalamnya akan tercermin dalam database.
Terpisah: Mengacu pada data yang sesuai dengan data dalam database, tetapi karena sesi ditutup, modifikasi yang dibuatnya tidak akan mempengaruhi catatan database.
Mari Kode Langsung:
Transaksi tx = session.begintransaction (); Pengguna pengguna = pengguna baru (); user.setname ("shun"); // Pengguna di sini belum disimpan ke database, dan tidak ada catatan yang sesuai dalam tabel database. Ini adalah transient state session.save (pengguna); tx.commit (); // Setelah komit, pengguna menjadi sesi status persisten.close (); // Karena sesi ditutup, pengguna terlepas saat ini, dan semua modifikasi tidak akan tercermin dalam database. Session session2 = sessionfactory.opensession (); tx = session2.begintransaction (); user.setname ("shun123"); session2.saveorupdate (pengguna); tx.commit (); // Ketika kami menelepon SaveorUpdate, pengguna menjadi gigih lagi, dan semua modifikasi akan tercermin dalam database. session2.close (); Kami melihat kodenya. Pertama, kami mendefinisikan pengguna objek. Sebelum disimpan, itu adalah keadaan sementara dan tidak ada catatan yang sesuai dalam database. Ketika kami menyimpan dan mengirimkan modifikasi, pengguna menjadi keadaan persisten dan ada catatan yang sesuai dalam database. Ketika kami menutup sesi, pengguna terlepas, dan perubahannya tidak akan tercermin dalam database kecuali kami secara manual memanggil pembaruan yang sesuai dan metode penambahan seperti SaveorUpdate. Dan apa yang harus kita lakukan saat kita ingin beralih dari keadaan gigih ke transien? Hapus saja secara langsung. Setelah dihapus, objek tidak akan memiliki catatan yang sesuai dalam database, yang akan menjadi sementara.
Transisi keadaan hibernasi relatif sederhana. Ketika sementara, tidak ada catatan yang sesuai untuk database, sementara persisten dan terpisah memiliki catatan yang sesuai. Namun, satu -satunya perbedaan adalah bahwa terlepas adalah keadaan yang hanya ada setelah sesi ditutup. Jadi apa perbedaan antara sementara dan terpisah? Ini hanya pertanyaan apakah ada catatan tabel database yang sesuai.
2) Setelah membaca statusnya, mari kita lihat cache Hibernate
Ada dua jenis cache untuk hibernate: cache level 1 dan level 2 cache.
Cache Level 1: Cache Level 1 yang disebut adalah cache internal.
Cache Level 2: Ini termasuk cache tingkat aplikasi, yang disebut cache sessionfactory di Hibernate, dan yang lainnya didistribusikan cache, yang merupakan metode cache teraman.
Mari kita lihat program secara langsung:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory sessionFactory = cfg.buildsessionFactory (); Sesi sesi = sessionfactory.opensession (); Pengguna pengguna = (user) session.load (user.class, new long (29)); System.out.println (user.getName ()); User user2 = (user) session.load (user.class, new long (29)); System.out.println (user2.getname ()); session.close (); } Lihat hasilnya:
Hibernate: Pilih user0_.user_id sebagai user1_0_0_, user0_.user_name sebagai user2_0_0_, user0_.age as age0_0_ dari pengguna pengguna0_ di mana user0_.user_id =? shun123123 shun123123
Dalam contoh kami menggunakan beban dua kali, tetapi hanya ada satu pernyataan SQL dalam hasilnya, yang menunjukkan bahwa itu hanya diminta sekali.
Mengapa? Inilah sebabnya mengapa cache hibernate bekerja. Setelah kueri pertama selesai, hibernasi entitas yang ditemukan dalam cache. Lain kali Anda memeriksa, cache akan diperiksa untuk melihat apakah ada entitas dengan ID yang sesuai. Jika ada, itu akan dikeluarkan secara langsung, jika tidak, kueri basis data akan dilakukan.
Mari kita ubah kode menjadi:
Pengguna pengguna = (user) session.load (user.class, new long (29)); System.out.println (user.getName ()); session.evict (user); // hapus pengguna dari cache user user2 = (user) session.load (user.class, baru long (29)); System.out.println (user2.getname ()); session.close ();
Lihat hasilnya:
Hibernate: Pilih user0_.user_id sebagai user1_0_0_, user0_.user_name sebagai user2_0_0_, user0_.age as age0_0_ dari pengguna pengguna0_ di mana user0_.user_id =? shun123123 hibernate: pilih user0_.user_id sebagai user1_0_0_, user0_.user_name sebagai user2_0_0_, user0_.age as Age0_0_ dari user user0_ di mana user0_.user_id =? shun123123
Setelah kami menghapus pengguna dari cache, kueri kedua juga langsung diambil dari database.
Level 2 Cache Talk
Mari kita lihat kelas entitas terlebih dahulu:
Pengguna kelas publik mengimplementasikan Serializable {Public Long ID; nama string pribadi; usia int pribadi; } File pemetaan dihilangkan, semua orang harus menulisnya.
Mari kita lihat file konfigurasi Hibernate:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property>
Kami melihat bahwa di provider_class kami menentukan ehcache, jadi kami juga membutuhkan ehcache.xml untuk ditempatkan di classpath:
<? xml versi = "1.0" encoding = "utf-8"?> <eHcache> <diskstore path = "java.io.path"/> <defaultcache maxeLementsInmemory = "10000" Eternal = "false" timetoideseconds = "120" TimeToLivesececonds = "120" 120 "overoids =" 120 "TimeToLivesECECONSEC =" 120 "120"
Selanjutnya, mari kita lihat metode pengujian:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory sessionFactory = cfg.buildsessionFactory (); Sesi sesi = sessionfactory.opensession (); Kueri kueri = session.createQuery ("Dari pengguna pengguna di mana name = 'shun123'"); Iterator iter = query.iterate (); while (iter.hasnext ()) {System.out.println ((((User) iter.next ()). getName ()); } session.close (); Session session2 = sessionfactory.opensession (); Query query2 = session2.createquery ("dari pengguna pengguna di mana name = 'shun123'"); Iterator iter2 = query2.iterate (); while (iter2.hasnext ()) {System.out.println ((((User) iter2.next ()). getName ()); } session2.close (); } Setelah berlari, Anda dapat melihat:
Hibernate: Pilih user0_.user_id sebagai col_0_0_ dari user user0_ di mana user0_.user_name = 'shun123' hibernate: pilih user0_.user_id sebagai user1_0_, user0_.user_name sebagai user2_0_0_, user1_. shun123 hibernate: pilih user0_.user_id sebagai col_0_0_ dari user user0_ di mana user0_.user_name = 'shun123' shun123
Kita dapat melihat bahwa itu hanya melakukan satu kalimat pencarian, dan ID tidak diambil untuk mencari pada kueri kedua, yang terutama disebabkan oleh cache sekunder.
Mari kita analisis kode dalam metode pengujian terlebih dahulu. Dalam metode pengujian, kami membuka dua sesi dan membuat dua kueri secara terpisah untuk kueri yang sama. Namun, kedua sesi tersebut dapat berbagi cache, yang merupakan cache tingkat kedua, cache level sesi. Selama sesi kami dibuat oleh sessionFactory yang sama, kami dapat berbagi cache sekunder untuk mengurangi interaksi dengan database.
Mari kita lihat makna dalam file konfigurasi:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property>
Jika kita perlu menggunakan cache sekunder, kita perlu mengonfigurasinya terlebih dahulu:
<nama properti = "hibernate.cache.use_second_level_cache"> true </preate>
Lakukan cache level kedua pembukaan akun, lalu lulus:
<nama properti = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheProvider </propert>
Tentukan kelas provisi untuk cache sekunder. Secara umum, kami menggunakan ehcache. Yang lain milik saya tidak digunakan untuk saat ini dan tidak terlalu jelas, jadi saya tidak akan membicarakannya untuk saat ini.
Seperti contoh kami sekarang, kami hanya perlu mengkonfigurasi dua di atas, yang sepenuhnya dapat berjalan secara normal dan menggunakan cache sekunder.
Jadi untuk apa kalimat ketiga?
<nama properti = "hibernate.cache.use_query_cache"> true </propert>
Konfigurasi ini menunjukkan bahwa kita perlu menggunakan cache saat meminta. Jika kita perlu menggunakan ini, kita harus memanggil kueri.
Mari kita lihat kode bersama (kami tidak akan mengaktifkan cache untuk saat ini):
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory sessionFactory = cfg.buildsessionFactory (); Sesi sesi = sessionfactory.opensession (); Kueri kueri = session.createQuery ("Dari pengguna pengguna di mana name = 'shun123'"); Daftar daftar = query.list (); untuk (int i = 0; i <list.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session.close (); Session session2 = sessionfactory.opensession (); Query query2 = session2.createquery ("dari pengguna pengguna di mana name = 'shun123'"); Daftar daftar2 = query2.list (); untuk (int i = 0; i <list2.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session2.close (); } Output hasil di sini adalah:
Hibernate: Pilih user0_.user_id sebagai user1_0_, user0_.user_name sebagai user2_0_, user0_.age as Age0_ dari user user0_ di mana user0_.user_name = 'shun123' shun123 hibernate: pilih user0_.user_id as user123 a user1123 asser123 hibernate: pilih user0_.user_id as User123 aSer1_3.3. usia0_ dari pengguna pengguna0_ di mana user0_.user_name = 'shun123' shun123
Kami melihat bahwa itu tidak menggunakan cache karena kami menggunakan daftar di sini, dan daftar hanya menulis dan tidak membaca cache. Jadi akan ada dua pertanyaan di sini.
Lalu mari kita ubah:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory sessionFactory = cfg.buildsessionFactory (); Sesi sesi = sessionfactory.opensession (); Kueri kueri = session.createQuery ("Dari pengguna pengguna di mana name = 'shun123'"); <span style = "latar belakang-warna: #ffffff;"> <span style = "color: #ff0000;"> query.setCeable (true); </span> </span> daftar daftar = query.list (); untuk (int i = 0; i <list.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session.close (); Session session2 = sessionfactory.opensession (); Query query2 = session2.createquery ("dari pengguna pengguna di mana name = 'shun123'"); <span style = "color: #ff0000;"> query2.setCeable (true); </span> daftar daftar2 = query2.list (); untuk (int i = 0; i <list2.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session2.close (); } Saya melihat dua kalimat merah kode. Ini adalah dua kode yang kami tambahkan untuk mengaktifkan cache kueri. Sekarang kita melihat hasilnya:
Hibernate: Pilih user0_.user_id sebagai user1_0_, user0_.user_name sebagai user2_0_, user0_.age as Age0_ dari user user0_ di mana user0_.user_name = 'shun123' shun123 shun123
Hanya ada satu pertanyaan yang tersisa, mengapa? Tepat di dua kode merah itu, kami menyalakan cache, ingat, itu perlu digunakan dua kali. Atur kedua cache kueri untuk di -cache.
Kriteria juga merupakan pendekatan yang serupa. Untuk menghindari sepatu anak -anak lupa bagaimana menulis kriteria, saya akan menempatkan beberapa kode:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory sessionFactory = cfg.buildsessionFactory (); Sesi sesi = sessionfactory.opensession (); Kriteria kriteria1 = session.createCriteria (user.class); kriteria1.setcacheable (true); kriteria1.add (pembatasan.eq ("name", "shun123")); Daftar daftar = criteria1.list (); untuk (int i = 0; i <list.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session.close (); Session session2 = sessionfactory.opensession (); Kriteria kriteria2 = session2.createCriteria (user.class); kriteria2.setcacheable (true); kriteria2.add (pembatasan.eq ("name", "shun123")); Daftar daftar2 = criteria2.list (); untuk (int i = 0; i <list2.size (); i ++) {System.out.println ((((User) list.get (i)). getName ()); } session2.close (); } Mari kita lihat hasilnya:
Hibernate: Pilih this_.user_id sebagai user1_0_0_, this_.user_name sebagai user2_0_0_, this_.age as age0_0_ dari pengguna this_ di mana this_.user_name =? shun123 shun123