Memetakan Pertanyaan Hibernate ke Kelas Tersuai

1. Gambaran keseluruhan

Apabila kita menggunakan Hibernate untuk mengambil data dari pangkalan data, secara lalai, ia menggunakan data yang diambil untuk membina keseluruhan grafik objek untuk objek yang diminta. Tetapi kadang-kadang kita mungkin hanya ingin mengambil sebahagian daripada data, lebih baik dalam struktur rata.

Dalam tutorial ringkas ini, kita akan melihat bagaimana kita dapat mencapainya di Hibernate menggunakan kelas khusus.

2. Entiti

Pertama, mari kita lihat entiti yang akan kita gunakan untuk mendapatkan data:

@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; // constructor, getters and setters } @Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String name; @OneToMany(mappedBy="department") private List employees; public Department(String name) { this.name = name; } // getters and setters  }

Di sini, kita mempunyai dua entiti - DeptEm Employee dan Department . Untuk kesederhanaan, mari kita anggap bahawa DeptEm Employee hanya boleh dimiliki oleh satu Jabatan.

Tetapi, sebuah Jabatan boleh mempunyai beberapa DeptEm Employees .

3. Kelas Hasil Pertanyaan Tersuai

Katakan kita mahu mencetak senarai semua pekerja dengan hanya nama dan nama jabatan mereka.

Biasanya, kami akan mengambil data ini dengan pertanyaan seperti ini:

Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee"); List deptEmployees = query.list();

Ini akan mengambil semua pekerja, semua harta benda mereka, jabatan yang berkaitan, dan semua hartanya.

Tetapi, dalam kes ini , ini mungkin agak mahal kerana kita hanya memerlukan nama pekerja dan nama jabatan.

Salah satu cara untuk hanya mendapatkan maklumat yang kita perlukan adalah dengan menentukan sifat dalam klausa pilih.

Tetapi, apabila kita melakukan ini, Hibernate mengembalikan senarai tatasusunan dan bukannya senarai Objek:

Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m"); List managers = query.list(); Object[] manager = (Object[]) managers.get(0); assertEquals("John Smith", manager[0]); assertEquals("Sales", manager[1]);

Seperti yang kita lihat, data yang dikembalikan agak rumit untuk diproses. Tetapi, untungnya, kita dapat membuat Hibernate mengisi data ini ke dalam kelas.

Mari kita lihat kelas Hasil yang akan kita gunakan untuk mengisi data yang diambil ke:

public class Result { private String employeeName; private String departmentName; public Result(String employeeName, String departmentName) { this.employeeName = employeeName; this.departmentName = departmentName; } public Result() { } // getters and setters }

Perhatikan bahawa kelas itu bukan entiti tetapi hanya POJO. Namun, kita juga dapat menggunakan entiti asalkan memiliki konstruktor yang mengambil semua atribut yang ingin kita isi sebagai parameter.

Kami akan melihat mengapa konstruktor penting di bahagian seterusnya.

4. Menggunakan Pembina dalam HQL

Sekarang, mari kita lihat HQL yang menggunakan kelas ini:

Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name)" + " from com.baeldung.hibernate.entities.DeptEmployee m"); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Di sini, kami menggunakan konstruktor yang kami tetapkan dalam kelas Hasil bersama dengan sifat yang ingin kami dapatkan. Ini akan mengembalikan senarai objek Hasil dengan data yang diisi dari lajur.

Seperti yang kita lihat, senarai yang dikembalikan lebih mudah diproses daripada menggunakan senarai susunan objek.

Penting untuk diperhatikan bahawa kita harus menggunakan nama kelas yang memenuhi syarat sepenuhnya dalam pertanyaan.

5. Menggunakan ResultTransformer

Alternatif untuk menggunakan konstruktor dalam pertanyaan HQL adalah dengan menggunakan ResultTransformer:

Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName" + " from com.baeldung.hibernate.entities.DeptEmployee m"); query.setResultTransformer(Transformers.aliasToBean(Result.class)); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Kami menggunakan Transformers. kaedah aliasToBean () untuk menggunakan data yang diambil untuk mengisi objek Hasil .

Oleh itu, kita mesti memastikan nama lajur atau aliasnya dalam pernyataan pilih sesuai dengan sifat kelas Hasil .

Perhatikan bahawa Query.setResultTransformer ( ResultTransformer ) sudah tidak digunakan lagi sejak Hibernate 5.2.

6. Kesimpulannya

Dalam artikel ini, kami melihat bagaimana kelas khusus dapat digunakan untuk mengambil data dalam bentuk yang mudah dibaca.

Kod sumber yang menyertai artikel ini terdapat di GitHub.