Въведение в 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()корен.
GO TO FULL VERSION