Hibernate Named Query

1. Ikhtisar

Kerugian utama dari HQL dan SQL yang tersebar di seluruh objek akses data adalah membuat kode tidak dapat dibaca. Oleh karena itu, mungkin masuk akal untuk mengelompokkan semua HQL dan SQL di satu tempat dan hanya menggunakan referensi mereka di kode akses data yang sebenarnya. Untungnya, Hibernate memungkinkan kita melakukan ini dengan kueri bernama.

Kueri bernama adalah kueri yang ditentukan secara statis dengan string kueri yang tidak dapat diubah sebelumnya. Mereka divalidasi ketika pabrik sesi dibuat, sehingga membuat aplikasi gagal dengan cepat jika terjadi kesalahan.

Pada artikel ini, kita akan melihat bagaimana mendefinisikan dan menggunakan Hibernate Dinamakan Query menggunakan @NamedQuery dan @NamedNativeQuery penjelasan.

2. Entitas

Pertama-tama mari kita lihat entitas 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 karyawan berdasarkan nomor karyawan mereka.

3. Kueri Bernama

Untuk mendefinisikan ini sebagai kueri bernama, kita akan menggunakan anotasi org.hibernate.annotations.NamedQuery . Ini memperluas javax .persistence.NamedQuery dengan fitur Hibernate.

Kami akan mendefinisikannya sebagai anotasi kelas DeptEmployee :

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

Penting untuk diperhatikan bahwa setiap anotasi @NamedQuery dilampirkan tepat ke satu kelas entitas atau superclass yang dipetakan. Namun, karena cakupan kueri bernama adalah seluruh unit persistensi, kita harus memilih nama kueri dengan hati-hati untuk menghindari benturan. Dan kami telah mencapai ini dengan menggunakan nama entitas sebagai awalan.

Jika kita memiliki lebih dari satu kueri bernama untuk sebuah entitas, kita akan menggunakan anotasi @NamedQueries untuk mengelompokkan ini:

@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 bahwa kueri HQL bisa menjadi operasi gaya DML. Jadi, tidak perlu hanya pernyataan pilih . Misalnya, kita dapat memiliki kueri pembaruan seperti pada DeptEmployee_UpdateEmployeeDesignation di atas.

3.1. Mengonfigurasi Fitur Query

Kita dapat menyetel berbagai fitur kueri dengan anotasi @NamedQuery . Mari kita lihat contohnya:

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

Di sini, kami telah mengonfigurasi interval waktu tunggu dan ukuran pengambilan. Selain keduanya, kita juga bisa mengatur fitur seperti:

  • dapat disimpan dalam cache - apakah kueri (hasil) dapat disimpan di cache atau tidak
  • cacheMode - mode cache yang digunakan untuk kueri ini; ini bisa berupa GET, IGNORE, NORMAL, PUT, atau REFRESH
  • cacheRegion - jika hasil kueri dapat disimpan dalam cache, beri nama wilayah cache kueri yang akan digunakan
  • komentar - komentar yang ditambahkan ke kueri SQL yang dihasilkan; ditargetkan untuk DBA
  • flushMode - mode flush untuk kueri ini, salah satu dari SELALU, AUTO, COMMIT, MANUAL, atau PERSISTENCE_CONTEXT

3.2. Menggunakan Kueri Bernama

Sekarang kita telah mendefinisikan query bernama, mari kita gunakan untuk mengambil seorang karyawan:

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

Di sini, kami telah menggunakan metode createNamedQuery . Ini mengambil nama kueri dan mengembalikan objek org.hibernate.query.Query .

4. Dinamakan Kueri Asli

Selain kueri HQL, kami juga dapat mendefinisikan SQL asli sebagai kueri bernama. Untuk melakukan ini, kita dapat menggunakan anotasi @NamedNativeQuery . Meskipun mirip dengan @NamedQuery , ini membutuhkan lebih banyak konfigurasi.

Mari jelajahi anotasi 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) )

Karena ini adalah kueri asli, kita harus memberi tahu Hibernate kelas entitas mana yang akan dipetakan hasilnya. Akibatnya, kami telah menggunakan properti resultClass untuk melakukan ini.

Cara lain untuk memetakan hasil adalah dengan menggunakan properti resultSetMapping . Di sini, kita dapat menentukan nama SQLResultSetMapping yang telah ditentukan sebelumnya .

Perhatikan bahwa kita hanya dapat menggunakan salah satu resultClass dan resultSetMapping .

4.1. Menggunakan Kueri Native Bernama

Untuk menggunakan kueri asli bernama, kita bisa 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 perbedaan antara kedua pendekatan ini adalah tipe pengembalian. Pendekatan kedua mengembalikan NativeQuery, yang merupakan subclass dari Query .

5. Prosedur dan Fungsi Tersimpan

Kita dapat menggunakan anotasi @NamedNativeQuery untuk menentukan panggilan ke prosedur dan fungsi yang tersimpan juga:

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

Perhatikan bahwa meskipun ini adalah kueri pembaruan, kami telah menggunakan properti resultClass . Ini karena Hibernate tidak mendukung kueri skalar asli murni. Dan cara untuk mengatasi masalah ini adalah dengan menyetel resultClass atau resultSetMapping.

6. Kesimpulan

Pada artikel ini, kami melihat bagaimana mendefinisikan dan menggunakan bernama HQL dan kueri asli.

Kode sumber tersedia di GitHub.