3.1 Pendahuluan

Hal berguna lainnya yang ingin saya bicarakan adalah NativeQuery . Seperti yang sudah Anda ketahui, menggunakan NativeQuery, Anda dapat menulis kueri dalam SQL asli. Namun, yang lebih menarik adalah Anda tidak harus menggunakan pemetaan kelas saat mendapatkan hasil kueri.

Saya lebih suka menunjukkan kepada Anda sebuah contoh:

List<Object[]> persons = session.createNativeQuery("SELECT * FROM Person").list();

Dalam contoh ini, kami tidak meneruskan kelas yang cocok dengan baris hasil kueri, melainkan hanya menggunakan larik objek Object.

Ini bisa berguna jika Anda ingin memilih hanya beberapa kolom dalam sebuah tabel. Contoh:


List<Object[]> persons = session.createNativeQuery("SELECT id, name FROM Person").list();
 
for(Object[] person : persons) {
    Number id = (Number) person[0];
    String name = (String) person[1];
}

Ini agak mirip dengan pendekatan JDBC saat Anda mendapatkan objek ResultSet dan membaca data dari barisnya.

Namun, Hibernate menawarkan cara berbeda untuk membuatnya lebih andal. Misalnya, Anda dapat menentukan jenis kolom yang ingin dikurangi. Contoh:


Query<Object[]> query = session.createNativeQuery("SELECT id, name FROM Person");
query.addScalar("id", StandardBasicTypes.LONG);
query.addScalar("name", StandardBasicTypes.STRING);
List<Object[]> persons = query.list();
 
for(Object[] person : persons) {
    Long id = (Long) person[0];
    String name = (String) person[1];
}

3.2 Pemetaan entitas

Anda juga dapat secara eksplisit menentukan kelas yang harus digunakan Hibernate saat mem-parsing hasil NativeQuery . Ini dapat dilakukan dengan berbagai cara.


Query<Person> query = session.createNativeQuery("SELECT * FROM Person")
    .addEntity(Person.class);
    .list();

Dan tentu saja, format lama yang bagus lho:


Query<Person> query = session.createNativeQuery("SELECT * FROM Person", Person.class).list();

Pendekatan pertama adalah pendekatan Hibernasi asli dan yang kedua adalah pendekatan JPA. Pendekatan JPA lebih nyaman dan ringkas, karena standar ini ditemukan setelah Hibernasi ada selama bertahun-tahun. Dan Hibernate berevolusi dan terpaksa mendukung pendekatan lama untuk menjaga kompatibilitas dengan versi lamanya.

Omong-omong, berkat pendekatannya, Hibernate memungkinkan Anda menghubungkan bukan hanya satu kelas ke pemetaan hasil kueri, tetapi beberapa kelas. Contoh:


List<Phone> results = session.createNativeQuery(
    "SELECT {ph.*}, {pr.*}" +
    "FROM Phone ph" +
    "JOIN Person pr ON ph.person_id = pr.id")
.addEntity("ph", Phone.class)
.addJoin("pr", "ph.person")
.list();
 
for (Phone. phone : results) {
           	assertNotNull( phone.getPerson().getName() );
}

Pendekatan menggunakan NativeQuery ini dapat digunakan untuk mempercepat pemilihan data dari database. Jika Anda tahu bahwa Anda tidak memerlukan beberapa kolom, Anda dapat meninggalkannya dalam permintaan.

Anda juga dapat memuat semua entitas anak sekaligus, bahkan jika Hibernate ingin menggunakan mekanisme Cache atau LazyLoading . Selain itu, entitas anak Anda mungkin memiliki banyak kolom dalam database, dan Anda hanya dapat memilih sebagian darinya.

3.3 Pemetaan DTO

Hibernasi juga memungkinkan Anda menggunakan kelas non-Entitas untuk memetakan hasilnya. Kelas yang tidak memiliki anotasi dan tidak dipetakan ke tabel mana pun.

Contoh:

public class PersonSummaryDTO {
    private Number id;
    private String name;

    public Number getId() {
    	return id;
    }

    public void setId(Number id) {
    	this.id = id;
    }

    public String getName() {
    	return name;
    }

    public void setName(String name) {
    	this.name = name;
	}
}

List<PersonSummaryDTO> dtos = session.createNativeQuery(
    "SELECT p.id as \"id\", p.name as \"name\" FROM Person p")
.setResultTransformer(Transformers.aliasToBean(PersonSummaryDTO.class) )
.list();

Karena tidak ada anotasi di kelas PersonSummaryDTO, nama kolom di kueri SQL harus sama persis dengan nama bidang di kelas PersonSummaryDTO.

Ini bisa sangat berguna jika Anda membaca data dari database eksternal yang terhubung dengan aplikasi Anda hanya dalam mode baca-saja. Artinya, Anda diberi akses ke tabel yang memiliki 50+ kolom, tabel tersebut menyimpan data dalam bentuk denormalisasi untuk mempercepat pemilihan.

Atau katakanlah seseorang memutuskan untuk menyimpan hierarki kelas dalam satu meja, dan dalam lima tahun meja ini telah berkembang pesat sehingga iblis akan mematahkan kakinya. Anda perlu memilih beberapa kolom dari tabel ini (Id dan nama pengguna) dan memberikannya kepada klien.

Saya pikir Anda mengerti, tetapi jika Anda ingin mempelajari topik ini lebih dalam, Anda dapat membaca lebih lanjut di tautan:

Kueri SQL Asli