2.1 Pengenalan kepada kelas Query

Ngomong-ngomong, satu lagi perkara penting ialah kelas pembantu Pertanyaan. Anda boleh melihatnya dalam contoh ini:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

Sebenarnya, Query ialah antara muka dan ia mempunyai beberapa pelaksanaan untuk kes yang berbeza. Tetapi untuk memudahkan, saya akan terus memanggilnya sebagai kelas. Ini, katakan, kelas dalam erti kata yang luas - dari segi OOP.

Catatan. Dulu ada dua kelas:

  • Pertanyaan untuk menerangkan pertanyaan.
  • TypedQuery untuk menerangkan pertanyaan dengan jenis yang diketahui.

Yang pertama muncul apabila Hibernate sudah wujud, dan belum ada generik lagi. Kemudian, selepas keluaran JDK 5, kelas lain telah ditambahkan pada Hibernate - TypedQuery, yang sudah menyokong penaipan hasil pertanyaan.

Tetapi, seingat saya, bermula dengan versi Hibernate ke-5, hanya satu kelas taip yang tinggal, dan ia kini dipanggil Query.

Cara standard untuk membuat Pertanyaan ialah:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

Anda belajar cara membuat objek Pertanyaan, tetapi bagaimanakah anda melaksanakan pertanyaan ini?

Ia lebih mudah di sini - kami hanya memanggil kaedah list() pada objek Pertanyaan:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

Kaedah list() mempunyai sinonim JPA, kaedah yang melakukan perkara yang sama tetapi dipanggil getResultList() . Anda kadangkala boleh melihatnya dalam kod yang ditulis oleh pengaturcara lain.

Ngomong-ngomong, jika pertanyaan menunjukkan bahawa hasilnya akan berada dalam satu hasil, maka lebih mudah untuk menggunakan kaedah uniqueResult() untuk memanggil pertanyaan .


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

Kaedah uniqueResult() mempunyai sinonim JPA, kaedah singleResult() . Ia diperkenalkan untuk keserasian Hibernate dengan standard JPA. Dia melakukan perkara yang sama.

2.2 Kaedah kelas pertanyaan

Malah, kelas Query mempunyai banyak kaedah yang berbeza. Di bawah ini saya akan bercakap tentang tiga lagi daripada mereka.

Yang pertama ialah kaedah stream() . Dan sinonim JPAnya getResultStream() .

Kedua-dua kaedah ini mengembalikan aliran data dan bukannya senarai. Pendekatan ini boleh menjadi sangat cekap apabila anda tidak memerlukan semua objek yang diperoleh hasil daripada pertanyaan sekaligus. Atau ada kemungkinan bahawa hanya yang pertama daripada mereka akan digunakan.

Contoh:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

Kaedah kedua ialah kaedah executeUpdate() . Anda boleh menulis pertanyaan yang akan mengubah sesuatu dalam pangkalan data. Dalam kes ini, Hibernate tidak perlu menggunakan transaksi baca sahaja apabila mengakses pangkalan data.

Contoh permintaan: kami memutuskan untuk meningkatkan tahap semua pengguna sebanyak 1.


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

Kaedah executeUpdate() akan mengembalikan bilangan baris yang sebenarnya telah diubah suai.

Dan akhirnya kaedah ketiga ialah scroll() . Kami akan memberitahu anda lebih lanjut mengenainya.

2.3 Kaedah kelas tatal

Kaedah ini agak serupa dengan kaedah stream() . Hanya ia membolehkan anda bergerak melalui senarai keputusan tanpa mengeluarkan keputusan sama sekali. Iaitu, anda boleh melaksanakan pertanyaan, kemudian tatalnya ke baris kejuta hasil dan mula membaca data dari sana.

Seperti iterator canggih.


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

Objek ScrollableResults mempunyai kaedah berikut:

Kaedah Penerangan
R dapatkan() Mengembalikan elemen semasa
seterusnya() Mengalihkan penuding ke elemen seterusnya
sebelumnya() Mengalihkan penuding ke elemen sebelumnya
tatal (saiz int) Tatal ke hadapan mengikut garisan saiz
kedudukan(int pos) Menjadikan nombor pos elemen sebagai elemen semasa
terakhir() Elemen semasa kini adalah yang terakhir
pertama () Elemen semasa kini adalah yang pertama
getRowNumber() Mengembalikan nombor baris semasa
setRowNumber() Menetapkan nombor baris semasa

Katakan anda menjalankan pertanyaan dan anda ingin mendapatkan elemen terakhir. Begini cara melakukannya:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();