Criteria API

All lectures for UZ purposes
Daraja, Dars
Mavjud

Criteria API bilan tanishuv

Hibernate da bazaga so'rov yozishning ikki usuli mavjud:

  • Hibernate Query Language
  • Criteria API

Birinchisi bilan allaqachon tanishgan edingiz, endi Criteria API bilan tanishadigan vaqt keldi. Bu juda kuchli vosita, qaysidir vaqtda hatto HQLdan ham mashhurroq bo'lgan. Hozirda u unchalik mashhur emas, ammo ba'zi vaziyatlarda HQL dan yaxshiroq yechim bo'ladi.

Hech bo'lmasa, Hibernate'ni o'rganib, Criteria API bilan tanishish kerak. Kichik bir misol yozamiz va uni tahlil qilamiz. Masalan, bazadan barcha xodimlarni (Employee) so'raymiz. Mana natijasi:


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

Ozroq murakkab ko'rinadi. Taqqoslash uchun o'sha so'rovni HQL da yozamiz:


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

Diqqat bilan qarang, ikkala misoldagi oxirgi ikki qator deyarli bir xil: biz Query obyektini yaratamiz va uning yordamida List olamiz. Bu bizga qolgan qatorlar ham bir xil narsalarni qilayotganini anglatadi.

Birinchi misolning 3 va 4-qatiga qarang:


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

Ularni bitta qatorga yozamiz:


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

Eslatib bormi? Agar biroz boshqacha ranglasak:


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

Ha, bu SELECT FROM so'rovini tuzishning ajoyib usuli.

Criteria API yordamida ishlash misollari

Yaxshi tushunish uchun men bir nechta misollar keltiraman.

So'rov 1. 10 mingdan yuqori maoshli barcha xodimlarni olish:


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

So'rov 2. 50 mingdan kam maoshli barcha xodimlarni olish:


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

So'rov 3. Vazifasida "test" so'zi bor xodimlarni olish:


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

So'rov 4. 10 mingdan 50 minggacha maoshli xodimlarni olish:


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

So'rov 5. Ismi null bo'lgan barcha xodimlarni olish:


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

So'rov 6. Ismi null bo'lmagan barcha xodimlarni olish:


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

Bu shunchaki so'rovni tuzishning ajoyib usuli:

  • Dastlab CriteriaBuilder obyektini olasiz.
  • Keyin uning yordamida CriteriaQuery obyektini yaratasiz.
  • Keyin CriteriaQuery va CriteriaBuilder yordamida unga qism-qism qo'shasiz.

Aynan shunday siz quyidagilar uchun parametrlarni belgilashingiz mumkin:

  • SELECT
  • FROM
  • WHERE

Shuningdek, CriteriaBuilder yordamida WHERE uchun turli shartlarni yaratishingiz mumkin.

Criteria API bilan ilg'or ishlash

Criteria API yordamida har qanday murakkablikdagi so'rovni tuzish mumkin. Va bu ajoyib yangilik. Misol uchun, siz WHERE uchun murakkab shart qo'ymoqchisiz. Uni qilishning usuli:


Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "тest%");
 
critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Agar AND ni OR o'rniga yozmoqchi bo'lsangiz, faqat oxirgi qatorni o'zgartirishingiz kerak:


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

Hammasi juda oddiy. Men bir nechta taqqoslovchi jadvalni keltiraman:

SQL Metod To'liq yozuv
a < b lt(a, b) builder.lt(a, b)
a > b gt(a, b) builder.gt(a, b)
a OR b or(a, b) builder.or(a, b)
a AND b and(a, b) builder.and(a, b)
a LIKE b like(a, b) builder.like(a, b)
a BETWEEN (c, d) between(a, c, d) builder.between(a, c, d)
a IS NULL isNull(a) builder.isNull(a)
a IS NOT NULL isNotNull(a) builder.isNotNull(a)

Oddiy emasmi?

So'rovga saralashni qanday qo'shamiz? Juda oddiy:


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

Shunchaki CrteriaQuery obyektida orderBy() metodini chaqirasiz va kerakli parametrlarni uzatasiz.

Bu so'rov HQL da qanday ko'rinishini aytay. Qiyoslang:

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

Faqat 3 narsani yodda tuting:

  • SELECT, FROM, WHERE kabi asosiy operatorlar CriteriaQuery obyektida chaqiriladi.
  • AND, OR, DESC kabi yordamchi operatorlar CriteriaBuilder obyektida chaqiriladi.
  • Maydon nomlari Root obyekti get() orqali olinadi.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION