Artikel ini menjelaskan metode operasi batch hibernate. Bagikan untuk referensi Anda, sebagai berikut:
Pemrosesan batch hibernasi
Hibernate mengoperasikan database sepenuhnya dengan cara yang berorientasi objek. Ketika objek persisten dioperasikan dengan cara yang berorientasi pada objek dalam program, itu akan secara otomatis dikonversi menjadi operasi pada database. Misalnya, saat memanggil metode Delete () sesi untuk menghapus objek yang persisten, Hibernate akan bertanggung jawab untuk menghapus catatan data yang sesuai; Saat menjalankan metode yang ditetapkan dari objek persisten, Hibernate akan secara otomatis dikonversi ke metode pembaruan yang sesuai dan memodifikasi catatan yang sesuai dari database.
Pertanyaannya adalah apakah 100.000 catatan perlu diperbarui secara bersamaan, apakah Anda perlu memuat 100.000 catatan satu per satu, dan kemudian hubungi metode yang ditetapkan secara bergantian - ini tidak hanya rumit, tetapi juga kinerja akses data sangat buruk. Untuk skenario pemrosesan batch ini, Hibernate menyediakan solusi pemrosesan batch. Berikut ini memperkenalkan cara menghadapi situasi pemrosesan batch ini dari tiga aspek: penyisipan batch, pembaruan batch dan penghapusan batch.
1 insert batch
Jika Anda perlu memasukkan 100.000 catatan ke dalam database, Hibernate biasanya menggunakan yang berikut:
Sesi sesi = sessionFactory.opensession (); transaksi tx = session.begintransaction (); untuk (int i = 0; i <100000; i ++) {pengguna u = pengguna baru (......); session.save (pelanggan);} tx.commit (); session.close ();Tetapi ketika program ini berjalan, ia akan selalu gagal di beberapa titik dan outofmemoryException dilemparkan. Ini karena sesi Hibernate memegang cache Level 1 yang diperlukan, dan semua instance pengguna akan di-cache di area cache tingkat sesi.
Untuk mengatasi masalah ini, ada ide yang sangat sederhana: secara teratur menyegarkan data yang di -cache oleh sesi ke dalam database, daripada selalu menyimpannya di tingkat sesi. Anda dapat mempertimbangkan merancang akumulator, yang meningkat dengan 1 untuk setiap contoh pengguna yang disimpan. Tentukan apakah data dalam cache sesi perlu disiram ke dalam database berdasarkan nilai akumulator.
Berikut ini cuplikan kode yang menambahkan 100.000 instance pengguna:
private void testUser () melempar Exception {// Sesi Sesi Buka Sesi = hibernateutil.currentsession (); // Mulai transaksi transaksi TX = session.begintransaction (); // loop 100 000 kali dan masukkan 100 000 catatan untuk (int i = 0; i <1000000; i ++) {// Buat Pengguna Instance User u1 = User baru (); u1.setname ("xxxxx" + i); u1.setage (i); u1.setnationality ("Cina"); // CACH Pengguna instance session.save (u1); // Setiap kali akumulator adalah kelipatan 20, siram data dalam sesi ke dalam database dan hapus cache sesi jika (i % 20 == 0) {session.flush (); session.clear (); tx.commit (); tx = session.begintransaction (); }} // Komit transaksi tx.Commit (); // Tutup transaksi hibernateutil.closesession ();}Dalam kode di atas, ketika saya%20 == 0, data yang di -cache pada sesi ditulis secara manual ke database dan transaksi diserahkan secara manual. Jika transaksi tidak diserahkan, data masih akan di -cache di kantor transaksi - belum memasuki database, yang juga akan menyebabkan pengecualian memori overflow.
Ini adalah pemrosesan cache tingkat sesi, dan cache sekunder Sesi juga harus dimatikan melalui konfigurasi berikut.
hibernate.cache.use_second_level_cache false
Catatan: Selain membersihkan cache tingkat sesi, yang terbaik adalah mematikan cache sekunder tingkat sesi. Kalau tidak, bahkan jika cache tingkat sesi dibersihkan secara manual, pengecualian dapat dilemparkan karena masih ada cache di tingkat sesiFactory.
2 pembaruan batch
Metode yang dijelaskan di atas juga cocok untuk data pembaruan batch. Jika Anda perlu mengembalikan beberapa baris data, Anda dapat menggunakan metode scroll () untuk memanfaatkan sepenuhnya keuntungan kinerja yang dibawa oleh kursor sisi server. Berikut ini adalah cuplikan kode untuk pembaruan batch:
private void testUser () melempar Exception {// Sesi Sesi Buka Sesi = hibernateutil.currentsession (); // Mulai transaksi transaksi tx = session.begintransaction (); // query semua catatan di tabel pengguna scrollableResults user = session.createqueery ("from user") .setCachemode (cachemode.ignore) .scroll (scrollmode.forward_only); Int Count = 0; // transaksi semua catatan di tabel pengguna while (user.next ()) {user u = (user) user.get (0); u.setname ("nama pengguna baru" + hitungan); // Ketika hitungan adalah kelipatan 20, siram hasil yang diperbarui dari sesi ke database IF (++ count % 20 == 0) {session.flush (); session.clear (); }} tx.Commit (); Hibernateutil.closesession ();} Dengan cara ini, meskipun pembaruan batch dapat dilakukan, efeknya sangat buruk. Efisiensi eksekusi tidak tinggi, dan kueri data diperlukan terlebih dahulu, dan kemudian pembaruan data dilakukan. Pembaruan ini akan menjadi pembaruan baris demi baris, yaitu, setiap kali baris catatan diperbarui, pernyataan pembaruan perlu dieksekusi, dan kinerjanya sangat rendah.
Untuk menghindari hal ini, Hibernate menyediakan sintaks HQL yang mirip dengan SQL untuk pembaruan batch dan penghapusan batch.
Pembaruan/Penghapusan Batch Gaya 3 SQL
Pernyataan HQL yang disediakan oleh Hibernate juga mendukung pembaruan batch dan menghapus sintaks.
Format sintaks dari pembaruan batch dan pernyataan hapus adalah sebagai berikut:
UPDATE | Hapus dari? Classname [where where_conditions]
Ada empat poin yang patut dicatat tentang format sintaks di atas:
● Dalam klausa From, kata kunci dari opsional. Artinya, Anda tidak bisa menulis dari kata kunci sama sekali.
● Hanya ada satu nama kelas dalam klausa From, dan nama kelas tidak dapat memiliki alias.
● Anda tidak dapat menggunakan koneksi dalam pernyataan HQL batch, tidak eksplisit maupun implisit. Tetapi subqueries dapat digunakan di klausa Where.
● Seluruh klausa di mana opsional.
Dengan asumsi bahwa Anda perlu mengubah atribut nama dari instance kelas pengguna, Anda dapat menggunakan cuplikan kode berikut:
private void testUser () melempar Exception {// Sesi Sesi Buka Sesi = hibernateutil.currentsession (); // Mulai transaksi transaksi TX = session.begintransaction (); // Tentukan pembaruan batch HQL Pernyataan String hqlupDate = "Perbarui nama pengguna set =: newname"; // Jalankan Pembaruan int updateDentities = session.createqueery (hqlupdate) .setstring ("newname", "name new") .executeUpdate (); // melakukan transaksi tx.commit (); Hibernateutil.closesession ();}Seperti yang dapat dilihat dari kode di atas, sintaks ini sangat mirip dengan sintaks ExecuteUpdate dari persiapan disiapkan. Bahkan, pembaruan batch HQL ini secara langsung meminjam dari pernyataan pembaruan sintaks SQL.
Catatan: Saat menggunakan sintaks pembaruan batch ini, Anda biasanya hanya perlu menjalankan pernyataan pembaruan SQL sekali untuk menyelesaikan semua pembaruan yang memenuhi catatan bersyarat. Tetapi mungkin juga perlu untuk menjalankan beberapa pernyataan pembaruan, karena ada kasus khusus seperti pemetaan warisan, seperti ada contoh seseorang, yang memiliki contoh subkelas pelanggan. Saat batch memperbarui instance orang, instance pelanggan juga perlu diperbarui. Jika Anda menggunakan strategi pemetaan sub-klasik atau penyusunan serikat pekerja, instance orang dan pelanggan disimpan dalam tabel yang berbeda, sehingga beberapa pernyataan pembaruan mungkin diperlukan.
Jalankan penghapusan HQL, dan gunakan metode query.executeupdate (). Berikut ini adalah cuplikan kode yang menghapus semua catatan di atas sekaligus:
private void testUser () melempar Exception {// Open Sesi Sesi Sesi Sesi = hibernateutil.currentsession (); // Mulai transaksi transaksi TX = session.begintransaction (); // Tentukan penghapusan batch HQL Pernyataan string hqlupdate = "hapus pengguna"; // Jalankan penghapusan batch int updateDentities = session.createQuery (hqlupdate) .executeUpdate (); // melakukan transaksi tx.commit (); // tutup sesi hibernateutil.closesession ();}Mengembalikan nilai integer dengan metode query.executeUpdate (), yang merupakan jumlah catatan yang dipengaruhi oleh operasi ini. Bahkan, operasi mendasar Hibernate dilakukan melalui JDBC. Oleh karena itu, jika ada batch pembaruan atau hapus operasi yang dikonversi menjadi beberapa pernyataan pembaruan atau hapus, metode ini mengembalikan jumlah catatan yang dipengaruhi oleh pernyataan SQL terakhir.
Saya berharap deskripsi dalam artikel ini akan membantu pemrograman Java semua orang berdasarkan kerangka hibernasi.