Penelitian utama dalam artikel ini adalah konten yang relevan dari kueri HQL hibernasi, sebagai berikut.
Hibernate Query Language (HQL) adalah pernyataan kueri yang sepenuhnya berorientasi objek dengan fungsi kueri yang sangat kuat; Ini memiliki polimorfisme, asosiasi dan karakteristik lainnya. Kueri HQL juga merupakan metode kueri yang secara resmi direkomendasikan oleh Hibernate.
Selanjutnya, kami menganalisis metode kueri yang relevan melalui studi kasus
Class.java:
Kelas Kelas Publik {/*ID Kelas*/Private Int ID;/*Nama kelas*/Nama String Privat;/*Hubungan antara kelas dan siswa*/set privat <siswa> Siswa; // oloskan metode setter dan getter}Student.java:
Siswa kelas publik {/*ID Siswa*/Private Int ID;/*Nama Siswa*/Nama String Privat;/*Hubungan antara Siswa dan Kelas*/Kelas Kelas Privat; // Hilangkan Metode Setter dan Getter}Class.hbm.xml:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <hibernate-pack package = "com." com. name="Classes" table="t_classes" lazy="false"> <id name="id"> <generator/generator/> </id> <property name="name"/> <!-- One-to-many mapping, inverse="true" means to hand over the relationship to the peer--> <set name="students" inverse="true"> <key column="classesid"/> <one-to-many/> </set> </belas> </hibernate-Mapping>
Student.hbm.xml:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <hibernate-package = "com." com. "com." " TABLE = "t_student"> <id name = "id"> <generator // id> <!-peta properti normal-> <properti name = "name"/> <!-pemetaan banyak-ke-satu, tambahkan kunci asing ke beberapa ujung-> <banyak-ke-satu nama = "class" column = "classid"/</class> </hibernate-papping> colum
/*Mengembalikan daftar Atribut Set Hasil, jenis elemen dan jenis atribut di kelas entitas adalah sama*/ daftar <string> student = session.createquery ("Pilih Nama dari Siswa"). Daftar (); /*Travel*/ for (iterator <string> iter = student.iterator (); iter.hasnext ();) {string name = (string) iter.next (); System.out.println (nama); }Catatan: Saat menanyakan satu atribut, set yang dikembalikan adalah koleksi, dan jenis elemen koleksi adalah jenis atribut.
/*Permintaan beberapa properti, mengembalikan array objek*/ daftar <objek []> siswa = session.creaqequery ("Pilih id, nama dari siswa"). Daftar (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Meminta beberapa atribut mengembalikan kumpulan array tipe objek. Ini mudah dimengerti. Saat menanyakan satu atribut adalah jenis elemen koleksi yang dikembalikan, itu adalah jenis atribut, tetapi bagaimana dengan banyak jenis? Itu harus menjadi array objek untuk diproses, yaitu, objek [].
/*Kami mengatur konstruktor yang sesuai untuk objek entitas, dan kemudian kami dapat mengembalikan kumpulan tipe objek entitas dengan menanyakan objek*/ daftar siswa = sesi. /*Travel*/ for (iterator iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getId () + "," + student.getName ()); }Catatan: Selain metode kedua kami mengembalikan array objek, kami juga dapat mengatur konstruktor yang sesuai untuk objek entitas, dan kemudian meminta objek dengan menanyakan objek, dan kemudian mengembalikan kumpulan jenis entitas.
/*Alias dapat digunakan*/ Daftar <objek []> Siswa = session.createqueery ("Pilih S.id, S.Name dari Siswa S"). Daftar (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } /*Return adalah kumpulan jenis objek entitas*/ daftar <spulhy> Siswa = session.createqueery ("From Student"). Daftar (); /*TransiP*/ for (iterator <shonish> iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); }Catatan: Entitas kueri dapat secara langsung menggunakan bentuk dari nama kelas dari kelas.
/*Gunakan Pilih untuk menggunakan Alias*/ Daftar <Sahwarah> Siswa = session.creequery ("Pilih S dari Siswa S"). Daftar (); /*TransiP*/ for (iterator <shonish> iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); }Catatan: Jika Anda ingin menggunakan kata kunci pilih, Anda harus menggunakan alias. Poin lain harus dicatat: HQL tidak mendukung bentuk Select *.
/ ** * Jika Anda menggunakan daftar untuk menanyakan objek entitas, pernyataan kueri akan dikeluarkan untuk mendapatkan data objek entitas * * hibernate: pilih student0_.id sebagai id0_, student0_.name sebagai name0_, * student0_.createTime sebagai createTime0_, student0_.classid sebagai classid0_ dari TeRETIME sebagai createTime0_, student0_.classid sebagai classid0_ dari TeReAry (Students.SEDENSED <list/ list/ list/ classes sebagai classid0_ dari Te createTime0_) Siswa "). Daftar (); /*Travel*/ for (iterator <sahisent> iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); }Catatan: Saat menggunakan metode .list () untuk meminta objek, hanya satu pernyataan yang akan dikeluarkan, yaitu, pernyataan yang memperoleh data objek fisik.
/*** Masalah n+1 akan terjadi. Yang disebut n+1 mengacu pada penerbitan n+1 pernyataan sql * * 1: mengeluarkan pernyataan yang menanyakan daftar id * hibernate: pilih student0_.id sebagai col_0_0_ dari t_student student0_ * n: menerbitkan n sql. * student0_.createTime sebagai createTime0_0_, student0_.classesid sebagai classIsid0_0_ * dari t_student student0_ di mana student0_.id =? * */ Iterator <Sahasiswa> iter = session.createqueery ("dari siswa"). Iterate (); /*Travel*/ while (iter.hasnext ()) {student student = (student) iter.next (); System.out.println (student.getName ()); }Catatan: Saat melakukan kueri objek melalui iterator (), pernyataan n+1 akan dikeluarkan. Pertama, pernyataan akan dikeluarkan untuk menanyakan ID objek entitas, dan kemudian pernyataan N akan dikeluarkan berdasarkan ID masing -masing untuk meminta objek N. Kinerja formal relatif buruk.
/*Menyimpan koleksi kueri di cache tingkat pertama, yaitu cache tingkat sesi*/ daftar <spulhy> student = session.createquery ("from student"). List (); /*TransiP*/ for (iterator <shonish> iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); } System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Avoid N+1 problem* * Because after performing Operasi daftar, data akan ditempatkan dalam cache sesi (cache tingkat pertama), ketika menggunakan iterate, * pertama, pernyataan yang diminta daftar ID akan dikeluarkan, dan kemudian data yang sesuai akan dimuat dalam cache sesuai dengan ID jika ada data yang ada di dalam Cache *, tidak ada laporan SQL yang akan dikeluarkan berdasarkan ID. Cache dapat meningkatkan kinerja, jika tidak masalah n +1 akan terjadi**/ iterator <spulhy> iter = sesi.CATATAN: Faktanya, Hibernate memberikan kueri iterator () untuk meningkatkan kinerja, jadi mengapa terlalu banyak membantu? Alasannya adalah ITerator () mengambil data dari cache tingkat pertama. Jika ada data dalam cache, efisiensinya tidak diragukan lagi akan sangat kuat. Namun, ketika saya meminta pertama kali, bagaimana mungkin ada data dalam cache? Ini mengarah pada masalah yang disebut N+1. Kode di atas dapat menghindari masalah N+1. Idenya adalah untuk menggunakan daftar () pertama untuk meminta, karena setelah daftar () diminta, data ada dalam ringkasan cache tingkat pertama, dan saat menggunakan iterator (), efisiensinya akan sangat tinggi.
/*Kueri sesuai dengan kondisi (alias biasanya digunakan di sini, yang lebih nyaman)*/ daftar <objek []> siswa = session.createquery ("SELECT S.ID, S.NAME DARI SISWA S Di mana S.Name seperti '%0%'"). Daftar (); /*Travel*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Kueri bersyarat sama dengan SQL asli, keduanya adalah tempat kata kunci. Selain itu, biasanya lebih nyaman untuk menggunakan alias. Program di atas adalah untuk menanyakan beberapa atribut, sehingga mengembalikan kumpulan jenis array objek, dan elemen -elemen dalam array objek adalah atribut yang sesuai.
/*Pemrograman chenged*/ daftar <objek []> Siswa = session.creequery ("SELECT S.ID, S.NAME DARI SISWA S Di mana S.Name Suka?") .SetParameter (0, "%0%") .list (); /*Travel*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Parameter dapat dilewati melalui placeholder, yang dapat mencegah injeksi SQL.
/*Pemrograman chip*/ daftar <objek []> Siswa = session.creequery ("SELECT S.ID, S.NAME DARI SISWA S Di mana S.Name Suka: MyName") .setParameter ("myName", "%0%") .list (); /*Array objek*/ untuk (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Seperti: Tidak ada ruang setelah myname colon, jika tidak kesalahan akan terjadi.
[java] Lihat salinan sederhana/ * mengadopsi metode dalam, hanya satu parameter formal yang dapat digunakan */ daftar <objek []> siswa = session.createquery ("pilih s.id, s.name dari siswa di mana s.id in (: ids)") .setParameterlist ("ids", objek baru [] {1, 2, 3, 4}) ("id", objek baru [] {1, 2, 3, 4, 5}) ("id", objek baru [] {1, 2, 3, 4,) /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }CATATAN: Hanya ada satu parameter formal dalam tanda kurung setelah masuk. Ketika kita mengatur nilai parameter, kita dapat melewati nilai melalui array objek.
/* Permintaan Siswa di tahun 2009-08, Anda dapat menghubungi fungsi pemformatan tanggal MySQL*/ daftar <objek []> Siswa = sesi. /*Travel*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"); /*Siswa dari 2009-08-01 hingga 2009-08-20 dapat menyebut fungsi pemformatan tanggal MySQL*/ daftar <objek []> Siswa = sesi. sdf.parse ("2009-08-20 23:59:59")) .list (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } / * Gunakan SELECT * Anda harus menggunakan pernyataan SQL asli, dan mirip dengan HQL menanyakan beberapa properti, sehingga mengembalikan kumpulan tipe array objek */ daftar <objek []> siswa = session.createSqlQuery ("Pilih * dari t_student"). List (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: HQL tidak mendukung bentuk kueri SELECT *, tetapi Hibernate mendukung pernyataan SQL asli. Kita dapat menggunakan pernyataan SQL untuk meminta. Selain itu, mirip dengan HQL's Query Multiple Atribut, sehingga mengembalikan kumpulan jenis array objek.
/*Kueri halaman, setFirStresult (1) berarti mulai dari data pertama; setmaxResult (2) berarti 2 bagian data ditampilkan per halaman*/ daftar siswa = sesi. /*Travel*/ for (iterator iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); } /*Kueri navigasi, s.classes.name menavigasi dari siswa ke kelas di kelas (ini menavigasi dari ujung ke ujung yang lebih sedikit, yang juga dimungkinkan)*/ Daftar <spinition> Siswa = sesi. /*Travel*/ for (iterator <sahisent> iter = student.iterator (); iter.hasnext ();) {student student = (student) iter.next (); System.out.println (student.getName ()); }Catatan: S.Classes.Name Dalam pernyataan kueri di atas adalah untuk mendapatkan nama kelas dari navigasi siswa ke kelas kelas. Anda juga dapat menavigasi secara terbalik: menavigasi dari kelas ke siswa dalam mendapatkan atribut tertentu. Selain itu, pernyataan kueri dalam program ini berarti meminta semua siswa dengan 2 di nama kelas.
/ *Koneksi bagian dalam, cukup gunakan kata kunci gabungan */ daftar <objek []> siswa = session.createqueery ("pilih c.name, s.name dari student s goin s.classes c") .list (); /*Transaksi*/ untuk (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Kata kunci dalam koneksi dalam adalah bergabung, dan koneksi masih dilakukan dengan menggunakan alias dan navigasi. Pernyataan kueri di atas berarti: permintaan nama kelas dan nama siswa dari tabel siswa dan tabel kelas (koneksi dalam berarti bahwa harus ada atribut yang layak dalam permintaan, seperti tidak ada kelas atau tidak ada siswa atau siswa yang tidak dapat menanyakan tanpa kelas).
/*Left goin menggunakan kata kunci kiri gabung*/ daftar <object []> student = session.creaqequery ("pilih c.name, s.name from student s left goint s.classes c") .list (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }CATATAN: Kata kunci yang digunakan untuk gabung kiri adalah gabungan. Pernyataan kueri di atas berarti: Dari tabel siswa dan kelas, permintaan nama kelas dan nama siswa. Karena itu adalah koneksi kiri, siswa tanpa kelas juga akan diminta.
[java] Lihat Salin Polos/*Kata kunci gabungan kanan adalah right goint*/ list <object []> student = session.createQuery ("pilih c.name, s.name from student s right goint s.classes c") .list (); /*TransiP*/ for (iterator <object []> iter = student.iterator (); iter.hasnext ();) {objek [] obj = (objek []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Catatan: Kata kunci menggunakan gabungan yang tepat adalah gabungan yang tepat. Pernyataan kueri di atas berarti: Dari tabel siswa dan kelas, permintaan nama kelas dan nama siswa. Karena itu adalah koneksi kanan, kelas tanpa siswa akan ditanya.
Long count = (long) session.createquery ("pilih Count (*) dari siswa"). Uniqueresult ();Catatan: Hanya kueri statistik yang dapat digunakan dalam HQL dengan *. uniqueresult () berarti hanya ada satu set hasil, dan tipe yang dikembalikan panjang.
/*Pernyataan kueri*/ string hql = "pilih c.name, count (s) dari kelas c bergabung dengan grup c.students s oleh c.name order by c.name"; Daftar <object []> Siswa = session.createQuery (HQL) .list (); /*Travel*/ for (int i = 0; i <student.size (); i ++) {objek [] obj = (objek []) student.get (i); System.out.println (obj [0] + "," + obj [1]); }Catatan: HQL juga mendukung pengelompokan, penyortiran, dll. Pernyataan di atas berarti: Permintaan nama masing -masing kelas dan query jumlah siswa di setiap kelas, grup berdasarkan nama kelas, urutkan berdasarkan nama kelas
Di atas adalah semua tentang contoh kode kueri HQL Hibernate dalam artikel ini, 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!