Pengenalan kepada API Kriteria

Terdapat dua cara untuk menulis pertanyaan pangkalan data dalam Hibernate:

  • Bahasa Pertanyaan Hibernate
  • API Kriteria

Anda sudah lama bertemu yang pertama, sudah tiba masanya untuk berkenalan dengan API Kriteria. Ini adalah alat yang sangat berkuasa, pada satu ketika ia lebih popular daripada HQL. Kini ia tidak begitu popular lagi, tetapi untuk beberapa tugasan ia pasti akan menjadi penyelesaian yang lebih baik daripada HQL.

Walau apa pun, anda tidak boleh belajar Hibernate tanpa membiasakan diri dengan API Kriteria. Mari kita tulis contoh kecil, dan kemudian kita akan menganalisisnya. Sebagai contoh, kami akan meminta semua pekerja (Pekerja) daripada pangkalan data. Inilah yang kami akan dapat:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Nampak rumit. Mari tulis pertanyaan HQL yang sama untuk perbandingan:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Ambil perhatian bahawa dua baris terakhir kedua-dua contoh adalah hampir sama: kami mencipta objek Pertanyaan dan menggunakannya untuk mendapatkan Senarai. Ini membayangkan bahawa barisan lain melakukan sesuatu yang serupa.

Lihat baris 3 dan 4 contoh pertama:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Mari kita tulis mereka dalam satu baris:

critQuery.select(critQuery.from(Employee.class));

Tidakkah ia mengingatkan anda tentang apa-apa? Dan jika anda mewarnakannya sedikit berbeza:

critQuery.select(critQuery.from(Employee.class));

Ya, ini adalah pembinaan rumit bagi pertanyaan SELECT FROM.

Contoh bekerja dengan API Kriteria

Untuk pemahaman yang lebih baik, saya hanya akan memberikan beberapa contoh.

Permintaan 1 . Dapatkan semua pekerja dengan gaji melebihi 10 ribu:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Permintaan 2 . Dapatkan semua pekerja dengan gaji kurang daripada 50 ribu:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Permintaan 3 . Dapatkan semua pekerja yang jawatannya mengandungi perkataan "ujian":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Permintaan 4 . Dapatkan semua pekerja dengan gaji 10 hingga 50 ribu:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Permintaan 5 . Dapatkan semua pekerja yang namanya batal:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Permintaan 6 . Dapatkan semua pekerja yang namanya tidak batal:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

Ini hanyalah cara yang rumit untuk membina pertanyaan:

  • Mula-mula anda mendapat objekPembina Kriteria.
  • Kemudian gunakannya untuk mencipta objekCriteriaQuery.
  • Kemudian anda mula menambah bahagian padanya denganCriteriaQueryDanPembina Kriteria.

Inilah cara anda boleh menetapkan parameter untuk:

  • PILIH
  • DARI
  • DI MANA

Juga menggunakanPembina Kriteriaanda boleh membina keadaan yang berbeza untuk WHERE.

Kerja lanjutan dengan API Kriteria

Menggunakan API Kriteria, anda boleh membina pertanyaan tentang sebarang kerumitan. Dan ini adalah berita baik. Sebagai contoh, anda mahu klausa WHERE yang kompleks. Begini cara melakukannya:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Jika anda ingin menulis DAN bukannya OR, maka anda hanya perlu menukar baris terakhir:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Semuanya sebenarnya sangat mudah. Biar saya berikan anda jadual dengan beberapa perbandingan:

SQL Kaedah Rekod penuh
a<b lt(a, b) builder.lt(a, b)
a > b gt(a, b) builder.gt(a, b)
a ATAU b atau(a,b) builder.or(a, b)
a DAN b dan(a,b) pembina.dan(a,b)
SUKA b seperti(a,b) builder.like(a, b)
a ANTARA (c, d) antara(a, c, d) pembina.antara(a, c, d)
a IS NULL isNull(a) builder.isNull(a)
a BUKAN NULL isNotNull(a) builder.isNotNull(a)

Semuanya mudah, bukan?

Dan bagaimana kita menambah pengisihan pada pertanyaan? Sangat ringkas:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Anda hanya memanggil objek ituCriteriaQuerykaedah orderBy() dan hantar parameter yang diperlukan kepadanya.

Begini rupa pertanyaan yang sama dalam HQL. Bandingkan:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Anda hanya perlu ingat 3 perkara:

  • Pengendali utama seperti SELECT, FROM, WHERE dipanggil pada objekCriteriaQuery.
  • Pengendali tambahan seperti AND, OR, DESC dipanggil pada objekPembina Kriteria.
  • Nama medan diambil daripada objek melalui get()akar.