Fungsi pengelompokan dan agregasi

Anda telah mengetahui cara membuat permintaan sederhana ke Criteria API. Mari kita lihat cara membuat kueri yang lebih kompleks.

Misalnya, kami ingin menulis kueri untuk menentukan jumlah karyawan di suatu perusahaan. Begini tampilannya di HQL:

select count(*) from Employee

Dan seperti ini di Criteria API:

CriteriaQuery<Long> critQuery = builder.createQuery(Long.class);
critQuery.select(builder.count(critQuery.from(Employee.class)));

Kode Java lengkap akan terlihat seperti ini:

CriteriaBuilder builder = session.getCriteriaBuilder();

CriteriaQuery<Long> critQuery = builder.createQuery(Long.class);
critQuery.select(builder.count(critQuery.from(Employee.class)));

Query<Long> query = session.createQuery(critQuery);
Long count = query.getSingleResult();

Dan itu sama dengan menggunakan HQL:

String hqlQuery = "select count(*) from Employee";

Query<Long> query = session.createQuery(hqlQuery);
Long count = query.getSingleResult();

Sekarang mari kita coba menghitung gaji rata-rata di perusahaan. Permintaan HQL akan terlihat seperti ini:

select avg(salary) from Employee

Dan seperti ini di Criteria API:

CriteriaQuery<Double> critQuery = builder.createQuery(Double.class);
critQuery.select(builder.avg( critQuery.from(Employee.class).get("salary")));

Kode Java lengkap akan terlihat seperti ini:

CriteriaBuilder builder = session.getCriteriaBuilder();

CriteriaQuery<Double> critQuery = builder.createQuery(Double.class);
critQuery.select(builder.avg( critQuery.from(Employee.class).get("salary")));

Query<Double> query = session.createQuery(critQuery);
Double avgSalary = query.getSingleResult();

Pembaruan Kriteria

Memodifikasi tabel semudah mendapatkan data darinya. Untuk melakukan ini, CriteriaBuilder memiliki metode khusus - createCriteriaUpdate() , yang membuat objekKriteriaPerbarui<T>Yang memperbarui entitas dalam database.

Mari kita naikkan gaji karyawan yang menerima kurang dari 10 ribu. Berikut tampilan kueri HQL ini:

update Employee set salary = salary+20000 where salary<=10000

Dan inilah tampilannya di Criteria API:

CriteriaUpdate<Employee> criteriaUpdate = builder.createCriteriaUpdate(Employee.class);
Root<Employee> root = criteriaUpdate.from(Employee.class);
criteriaUpdate.set("salary", "salary+20000");
criteriaUpdate.where(builder.lt(root.get("salary"), 10000));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaUpdate).executeUpdate();
transaction.commit();

KriteriaHapus

Dan menghapus catatan bahkan lebih mudah daripada mengubahnya. Untuk melakukan ini, ada metode khusus createCriteriaDelete() , yang membuat objekKriteriaHapus<T>.

Mari kita potong semua karyawan yang tidak memiliki nilai: gajinya kurang dari 10 ribu. Berikut tampilan kueri HQL ini:

delete from Employee where salary<=10000

Dan inilah tampilannya di Criteria API:

CriteriaDelete<Employee> criteriaDelete = builder.createCriteriaDelete(Employee.class);
Root<Employee> root = criteriaDelete.from(Employee.class);
criteriaDelete.where(builder.lt(root.get("salary"), 10000));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaDelete).executeUpdate();
transaction.commit();

Manfaat API Kriteria

Jadi apa manfaat API Kriteria? Pertanyaan rumit, HQL pasti akan lebih kompak.

Pertama, kueri HQL tidak terlalu pendek jika Anda perlu memberikan parameter kepada mereka. Membandingkan:

Kami mempertimbangkan jumlah karyawan dengan gaji kurang dari 10 ribu
HQL
String hqlQuery = "from Employee where salary < :sal";
Query<Employee> query = session.createQuery(hqlQuery);
query.setParametr("sal", 10000);
List<Employee> results = query.getResultList();
Kriteria API
CriteriaBuilder builder = session.getCriteriaBuilder();
critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 10000));
Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Kedua, sangat sering ada situasi ketika kueri perlu dibuat secara dinamis. Misalnya, Anda memiliki halaman web yang memfilter karyawan, apartemen, dan apa saja. Dan jika beberapa parameter tidak penting bagi pengguna, maka dia tidak menunjukkannya. Karenanya, null diteruskan ke server sebagai gantinya.

Inilah tugas Anda: memilih karyawan dengan profesi tertentu (pekerjaan), gaji (gaji) dan tahun kerja (TAHUN (join_date)). Tetapi jika nilai parameter apa pun adalah nol, jangan gunakan itu di filter.

Maka kueri HQL akan terlihat seperti ini:

from Employee
where (occupation = :ocp)
   	and (salary = :sal)
   	and ( YEAR(join_date) = :jny)

Tapi itu tidak akan berfungsi dengan benar, karena kami ingin jika parameter "jny" adalah nol, permintaan akan terlihat seperti ini:

from Employee
where (occupation = :ocp)
   	and (salary = :sal)

Kami dapat mencoba menulis ulang permintaan dengan memeriksa parameter untuk nol, lalu kami akan mendapatkan sesuatu seperti ini:

from Employee
where (occupation = :ocp or :ocp is null)
   	and (salary = :sal or :sal is null)
   	and ( YEAR(join_date)= :jny or :jny is null)

Lihat bagaimana kenyataan menjadi lebih rumit? Kenyataan memang sering seperti ini :)

Tapi filternya bisa lebih rumit lagi. Bagaimana dengan mencari pengguna yang memiliki tugas dengan kata "beli" di dalamnya? Atau pengguna yang memiliki tugas yang terlambat?

from Employee
where (occupation = :ocp)
   	and (salary = :sal)
   	and (YEAR(join_date) = :jny)
   	and (tasks.name like '%buy%')
   	and (tasks.deadline < curdate())

Jika Anda menulis atau null di suatu tempat dalam kueri seperti itu , maka ini tidak akan membatalkan gabungan antar tabel.

Jadi dalam praktiknya, saat Anda melakukan filter kompleks apa pun pada bidang beberapa tabel, Criteria API dapat membantu Anda. Begitu seterusnya.

Rincian lebih lanjut dapat ditemukan di dokumentasi resmi .