Въведение в API на критериите

Има два начина за писане на заявки за база данни в Hibernate:

  • Hibernate Query Language
  • API за критерии

Вече сте се запознали с първия преди много време, време е да се запознаете с Criteria API. Това е много мощен инструмент, в няHowъв момент беше дори по-популярен от HQL. Сега вече не е толкова популярен, но за някои задачи определено ще бъде по-добро решение от HQL.

Във всеки случай не можете да научите Hibernate, без да се запознаете с Criteria API. Нека напишем малък пример и след това ще го анализираме. Например ще изискаме всички служители (Employee) от базата данни. Ето Howво ще получим:

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

Изглежда сложно. Нека напишем същата HQL заявка за сравнение:

String hqlQuery = "from Employee";

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

Обърнете внимание, че последните два реда и в двата примера са почти идентични: създаваме обект Query и го използваме, за да получим списък. Това подсказва, че останалите редове правят нещо идентично.

Вижте редове 3 и 4 от първия пример:

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

Нека ги напишем в един ред:

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

Нищо ли не ви напомня? И ако го оцветите малко по-различно:

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

Да, това е толкова сложна конструкция на заявката SELECT FROM.

Примери за работа с Criteria API

За по-добро разбиране ще дам само няколко примера.

Заявка 1 . Вземете всички служители със заплата над 10 хиляди:

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

Заявка 2 . Вземете всички служители със заплата под 50 хиляди:

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

Заявка 3 . Вземете всички служители, чиято длъжност съдържа думата "тест":

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

Заявка 4 . Вземете всички служители със заплата от 10 до 50 хиляди:

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

Заявка 5 . Вземете всички служители, чието име е null:

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

Заявка 6 . Вземете всички служители, чието име не е null:

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

Това е просто толкова труден начин за създаване на заявка:

  • Първо получавате обектаCriteriaBuilder.
  • След това го използвайте, за да създадете обектCriteriaQuery.
  • След това започвате да добавяте части към него сCriteriaQueryИCriteriaBuilder.

Ето How можете да зададете параметри за:

  • ИЗБЕРЕТЕ
  • ОТ
  • КЪДЕТО

Също така използвайкиCriteriaBuilderможете да конструирате различни условия за WHERE.

Разширена работа с Criteria API

Използвайки Criteria API, можете да създадете заявка с всяHowва сложност. И това е страхотна новина. Например искате сложна клауза WHERE. Ето How да го направите:

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

Ако искате да напишете И instead of ИЛИ, тогава трябва да промените само последния ред:

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

Всичко всъщност е много просто. Нека ви дам table с няколко сравнения:

SQL Метод Пълен запис
a<b lt(a, b) builder.lt(a, b)
a > b gt(a, b) builder.gt(a, b)
a ИЛИ b or (a,b) builder.or(a, b)
а И б и (а, б) строител.и(а,б)
a ХАРЕСВАНЕ b харесвам(a,b) builder.like(a, b)
a МЕЖДУ (c, d) между (a, c, d) builder.between(a, c, d)
a Е НУЛЕВ isNull(a) builder.isNull(a)
a НЕ Е НУЛЕВ isNotNull(a) builder.isNotNull(a)

Всичко е просто, нали?

И How да добавим сортиране към заявката? Много просто:

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

Просто се обаждате на обектаCriteriaQueryметод orderBy() и му предайте необходимите параметри.

Ето How би изглеждала същата заявка в HQL. Сравнете:

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

Просто трябва да запомните 3 неща:

  • Ключови оператори като SELECT, FROM, WHERE се извикват върху обектCriteriaQuery.
  • Спомагателни оператори като AND, OR, DESC се извикват върху обектаCriteriaBuilder.
  • Имената на полетата се вземат от обекта чрез get()корен.