Fungsi pengelompokan dan pengagregatan

Anda telah mengetahui cara membuat permintaan mudah kepada API Kriteria. Mari lihat cara membuat pertanyaan yang lebih kompleks.

Sebagai contoh, kami ingin menulis pertanyaan untuk menentukan bilangan pekerja dalam syarikat. Begini rupanya di HQL:

select count(*) from Employee

Dan seperti ini pada API Kriteria:

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

Kod Java lengkap akan kelihatan 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 ia adalah sama menggunakan HQL:

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

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

Sekarang mari kita cuba mengira purata gaji dalam syarikat. Pertanyaan HQL akan kelihatan seperti ini:

select avg(salary) from Employee

Dan seperti ini pada API Kriteria:

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

Kod Java lengkap akan kelihatan 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();

Kemas kini Kriteria

Mengubah suai jadual adalah semudah mendapatkan data daripadanya. Untuk melakukan ini, CriteriaBuilder mempunyai kaedah khas - createCriteriaUpdate() , yang mencipta objekKemas Kini Kriteria<T>Yang mengemas kini entiti dalam pangkalan data.

Jom naikkan gaji pekerja yang terima kurang 10 ribu. Inilah rupa pertanyaan HQL ini:

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

Dan ini adalah bagaimana ia akan kelihatan pada API Kriteria:

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();

KriteriaPadam

Dan memadam rekod adalah lebih mudah daripada menukarnya. Untuk melakukan ini, terdapat kaedah khas createCriteriaDelete() , yang mencipta objekKriteriaPadam<T>.

Mari kita potong semua pekerja yang tidak mempunyai nilai: gaji mereka tidak sampai 10 ribu. Inilah rupa pertanyaan HQL ini:

delete from Employee where salary<=10000

Dan ini adalah bagaimana ia akan kelihatan pada API Kriteria:

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();

Faedah API Kriteria

Jadi apakah faedah API Kriteria? Pertanyaan menyusahkan, HQL pasti akan lebih padat.

Pertama, pertanyaan HQL tidak begitu singkat jika anda perlu menghantar parameter kepada mereka. Bandingkan:

Kami menganggap bilangan pekerja dengan gaji kurang daripada 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();
API Kriteria
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, selalunya terdapat situasi apabila pertanyaan perlu dibina secara dinamik. Contohnya, anda mempunyai halaman web yang menapis pekerja, pangsapuri dan apa-apa sahaja. Dan jika beberapa parameter tidak penting kepada pengguna, maka dia tidak menunjukkannya. Oleh itu, null dihantar ke pelayan sebaliknya.

Berikut ialah tugas anda: untuk memilih pekerja dengan profesion tertentu (pekerjaan), gaji (gaji) dan tahun pekerjaan (TAHUN (tarikh_serta)). Tetapi jika mana-mana nilai parameter adalah batal, maka jangan gunakannya dalam penapis.

Kemudian pertanyaan HQL akan kelihatan seperti ini:

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

Tetapi ia tidak akan berfungsi dengan betul, kerana kami mahu jika parameter "jny" adalah batal, maka permintaan akan kelihatan seperti ini:

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

Kita boleh cuba menulis semula permintaan dengan menyemak parameter untuk null, maka kita akan mendapat 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 realiti menjadi lebih rumit? Realiti selalunya begini :)

Tetapi penapis boleh menjadi lebih rumit. Bagaimana pula dengan mencari pengguna yang mempunyai tugasan dengan perkataan "beli" di dalamnya? Atau pengguna yang mempunyai tugas tertunggak?

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 batal di suatu tempat dalam pertanyaan sedemikian , maka ini tidak akan membatalkan gabungan antara jadual.

Jadi dalam amalan, apabila anda melakukan sebarang penapis kompleks pada medan beberapa jadual, API Kriteria hanya boleh membantu anda. Begitu seterusnya.

Butiran lanjut boleh didapati dalam dokumentasi rasmi .