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.
GO TO FULL VERSION