Pertanyaan Dinamakan Hibernate

1. Gambaran keseluruhan

Kelemahan utama apabila HQL dan SQL tersebar di objek akses data adalah bahawa ia membuat kod tidak dapat dibaca. Oleh itu, mungkin masuk akal untuk mengumpulkan semua HQL dan SQL di satu tempat dan hanya menggunakan rujukan mereka dalam kod akses data sebenar. Nasib baik, Hibernate membolehkan kami melakukan ini dengan pertanyaan yang dinamakan.

Pertanyaan bernama adalah pertanyaan yang ditentukan secara statik dengan rentetan pertanyaan yang tidak dapat ditukar yang telah ditentukan sebelumnya. Mereka disahkan ketika kilang sesi dibuat, sehingga membuat aplikasi gagal cepat jika terjadi kesalahan.

Dalam artikel ini, kita akan melihat bagaimana untuk menentukan dan menggunakan Hibernate Dinamakan Queries menggunakan @NamedQuery dan @NamedNativeQuery penjelasan.

2. Entiti

Mari lihat dahulu entiti yang akan kita gunakan dalam artikel ini:

@Entity public class DeptEmployee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String employeeNumber; private String designation; private String name; @ManyToOne private Department department; // getters and setters }

Dalam contoh kami, kami akan mengambil pekerja berdasarkan nombor pekerja mereka.

3. Pertanyaan Dinamakan

Untuk menentukan ini sebagai pertanyaan bernama, kami akan menggunakan anotasi org.hibernate.annotations.NamedQuery . Ia memperluas javax .persistence.NamedQuery dengan ciri Hibernate.

Kami akan menentukannya sebagai anotasi kelas DeptEm Employee :

@org.hibernate.annotations.NamedQuery(name = "DeptEmployee_findByEmployeeNumber", query = "from DeptEmployee where employeeNumber = :employeeNo") 

Penting untuk diperhatikan bahawa setiap anotasi @NamedQuery dilampirkan pada satu kelas entiti atau superclass yang dipetakan. Tetapi, kerana ruang lingkup pertanyaan yang disebut adalah keseluruhan unit ketekunan, kita harus memilih nama pertanyaan dengan berhati-hati untuk mengelakkan pertembungan. Dan kami telah mencapainya dengan menggunakan nama entiti sebagai awalan.

Sekiranya kami mempunyai lebih daripada satu pertanyaan bernama untuk entiti, kami akan menggunakan anotasi @NamedQueries untuk mengumpulkannya:

@org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindByEmployeeNumber", query = "from DeptEmployee where employeeNumber = :employeeNo"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where designation = :designation"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_UpdateEmployeeDepartment", query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo"), ... })

Perhatikan bahawa pertanyaan HQL boleh menjadi operasi gaya DML. Jadi, ia tidak perlu menjadi penyataan terpilih sahaja. Sebagai contoh, kita boleh mempunyai pertanyaan kemas kini seperti di DeptEmemployee_UpdateEmemployeeDesignation di atas.

3.1. Mengkonfigurasi Ciri-ciri Pertanyaan

Kami boleh menetapkan pelbagai ciri pertanyaan dengan anotasi @NamedQuery . Mari lihat contoh:

@org.hibernate.annotations.NamedQuery( name = "DeptEmployee_FindAllByDepartment", query = "from DeptEmployee where department = :department", timeout = 1, fetchSize = 10 )

Di sini, kami telah mengkonfigurasi selang waktu tamat dan ukuran pengambilan. Selain daripada kedua-duanya, kami juga dapat menetapkan ciri seperti:

  • cacheable - sama ada pertanyaan (hasil) boleh disimpan dalam cache atau tidak
  • cacheMode - mod cache yang digunakan untuk pertanyaan ini; ini boleh menjadi salah satu GET, IGNORE, NORMAL, PUT, atau REFRESH
  • cacheRegion - jika hasil pertanyaan dapat disimpan dalam cache, beri nama wilayah cache pertanyaan yang akan digunakan
  • komen - komen yang ditambahkan pada pertanyaan SQL yang dihasilkan; disasarkan untuk DBA
  • flushMode - mod flush untuk pertanyaan ini, salah satu SELALU, AUTO, KOMIT, MANUAL, atau PERSISTENCE_CONTEXT

3.2. Menggunakan Pertanyaan Dinamakan

Sekarang setelah kami menentukan pertanyaan yang dinamakan, mari gunakannya untuk mendapatkan pekerja:

Query query = session.createNamedQuery("DeptEmployee_FindByEmployeeNumber", DeptEmployee.class); query.setParameter("employeeNo", "001"); DeptEmployee result = query.getSingleResult(); 

Di sini, kami telah menggunakan kaedah createNamedQuery . Ia mengambil nama pertanyaan dan mengembalikan objek org.hibernate.query.Query .

4. Dinamakan Native Query

Selain pertanyaan HQL, kita juga dapat menentukan SQL asli sebagai pertanyaan bernama. Untuk melakukan ini, kita boleh menggunakan anotasi @NamedNativeQuery . Walaupun serupa dengan @NamedQuery , ia memerlukan sedikit lebih banyak konfigurasi.

Mari terokai penjelasan ini menggunakan contoh:

@org.hibernate.annotations.NamedNativeQueries( @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee_GetEmployeeByName", query = "select * from deptemployee emp where name=:name", resultClass = DeptEmployee.class) )

Oleh kerana ini adalah pertanyaan asli, kita harus memberitahu Hibernate kelas entiti apa untuk memetakan hasilnya. Oleh itu, kami telah menggunakan harta hasilClass untuk melakukan ini.

Kaedah lain untuk memetakan hasilnya adalah dengan menggunakan properti hasilSetMapping . Di sini, kita dapat menentukan nama SQLResultSetMapping yang telah ditentukan .

Perhatikan bahawa kita hanya dapat menggunakan satu dari hasilClass dan resultSetMapping .

4.1. Menggunakan Pertanyaan Asli yang Dinamakan

Untuk menggunakan pertanyaan asli bernama, kita boleh menggunakan Session.createNamedQuery () :

Query query = session.createNamedQuery("DeptEmployee_FindByEmployeeName", DeptEmployee.class); query.setParameter("name", "John Wayne"); DeptEmployee result = query.getSingleResult();

Atau Session.getNamedNativeQuery () :

NativeQuery query = session.getNamedNativeQuery("DeptEmployee_FindByEmployeeName"); query.setParameter("name", "John Wayne"); DeptEmployee result = (DeptEmployee) query.getSingleResult();

Satu-satunya perbezaan antara kedua pendekatan ini adalah jenis pengembalian. Pendekatan kedua mengembalikan NativeQuery, yang merupakan subkelas Query .

5. Prosedur dan Fungsi yang Disimpan

Kami boleh menggunakan anotasi @NamedNativeQuery untuk menentukan panggilan ke prosedur dan fungsi yang disimpan juga:

@org.hibernate.annotations.NamedNativeQuery( name = "DeptEmployee_UpdateEmployeeDesignation", query = "call UPDATE_EMPLOYEE_DESIGNATION(:employeeNumber, :newDesignation)", resultClass = DeptEmployee.class)

Perhatikan bahawa walaupun ini adalah pertanyaan kemas kini, kami telah menggunakan properti resultClass . Ini kerana Hibernate tidak menyokong pertanyaan skalar asli yang tulen. Dan cara mengatasi masalahnya adalah dengan menetapkan resultClass atau resultSetMapping.

6. Kesimpulannya

Dalam artikel ini, kami melihat cara menentukan dan menggunakan HQL bernama dan pertanyaan asli.

Kod sumber boleh didapati di GitHub.