Hibernate - Критерии запросов
Hibernate предоставляет альтернативные способы управления объектами и, в свою очередь, данными, доступными в таблицах СУБД. Одним из методов является Criteria API, который позволяет программно создать объект запроса критериев, в котором можно применять правила фильтрации и логические условия.
Гибернация Session интерфейс обеспечивает createCriteria() метод, который можно использовать для создания Criteria объект, который возвращает экземпляры класса объекта персистентности, когда ваше приложение выполняет запрос критериев.
Ниже приводится простейший пример запроса критериев, который просто возвращает каждый объект, соответствующий классу Employee.
Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();
Ограничения с критериями
Вы можете использовать add() метод доступен для Criteriaобъект, чтобы добавить ограничение для критериального запроса. Ниже приведен пример добавления ограничения для возврата записей с окладом, равным 2000 -
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();
Ниже приведены еще несколько примеров, охватывающих различные сценарии, которые можно использовать в соответствии с требованиями.
Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));
// To get records having salary less than 2000
cr.add(Restrictions.lt("salary", 2000));
// To get records having fistName starting with zara
cr.add(Restrictions.like("firstName", "zara%"));
// Case sensitive form of the above restriction.
cr.add(Restrictions.ilike("firstName", "zara%"));
// To get records having salary in between 1000 and 2000
cr.add(Restrictions.between("salary", 1000, 2000));
// To check if the given property is null
cr.add(Restrictions.isNull("salary"));
// To check if the given property is not null
cr.add(Restrictions.isNotNull("salary"));
// To check if the given property is empty
cr.add(Restrictions.isEmpty("salary"));
// To check if the given property is not empty
cr.add(Restrictions.isNotEmpty("salary"));
Вы можете создать условия И или ИЛИ, используя ограничения LogicalExpression следующим образом:
Criteria cr = session.createCriteria(Employee.class);
Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");
// To get records matching with OR conditions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );
// To get records matching with AND conditions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();
Хотя все вышеперечисленные условия можно использовать непосредственно с HQL, как описано в предыдущем руководстве.
Разбиение на страницы с использованием критериев
В интерфейсе критериев для разбивки на страницы есть два метода.
Sr. No. | Метод и описание |
---|---|
1 | public Criteria setFirstResult(int firstResult) Этот метод принимает целое число, которое представляет первую строку в наборе результатов, начиная со строки 0. |
2 | public Criteria setMaxResults(int maxResults) Этот метод сообщает Hibernate получить фиксированное число maxResults объектов. |
Используя вместе два вышеуказанных метода, мы можем создать компонент подкачки в нашем веб-приложении или приложении Swing. Ниже приведен пример, который вы можете расширить, чтобы получать по 10 строк за раз.
Criteria cr = session.createCriteria(Employee.class);
cr.setFirstResult(1);
cr.setMaxResults(10);
List results = cr.list();
Сортировка результатов
API критериев предоставляет org.hibernate.criterion.Order, чтобы отсортировать набор результатов в порядке возрастания или убывания в соответствии с одним из свойств вашего объекта. Этот пример демонстрирует, как вы могли бы использовать класс Order для сортировки набора результатов:
Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));
// To sort records in descening order
cr.addOrder(Order.desc("salary"));
// To sort records in ascending order
cr.addOrder(Order.asc("salary"));
List results = cr.list();
Прогнозы и агрегаты
API критериев предоставляет org.hibernate.criterion.Projectionsclass, который можно использовать для получения среднего, максимального или минимального значений свойств. Класс Projection похож на класс Restrictions тем, что он предоставляет несколько статических фабричных методов для полученияProjection экземпляры.
Ниже приведены несколько примеров, охватывающих различные сценарии, которые могут использоваться в соответствии с требованиями.
Criteria cr = session.createCriteria(Employee.class);
// To get total row count.
cr.setProjection(Projections.rowCount());
// To get average of a property.
cr.setProjection(Projections.avg("salary"));
// To get distinct count of a property.
cr.setProjection(Projections.countDistinct("firstName"));
// To get maximum of a property.
cr.setProjection(Projections.max("salary"));
// To get minimum of a property.
cr.setProjection(Projections.min("salary"));
// To get sum of a property.
cr.setProjection(Projections.sum("salary"));
Пример критериев запросов
Рассмотрим следующий класс POJO -
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}
Давайте создадим следующую таблицу EMPLOYEE для хранения объектов Employee -
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
Ниже будет файл сопоставления.
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">
<meta attribute = "class-description">
This class contains the employee detail.
</meta>
<id name = "id" type = "int" column = "id">
<generator class="native"/>
</id>
<property name = "firstName" column = "first_name" type = "string"/>
<property name = "lastName" column = "last_name" type = "string"/>
<property name = "salary" column = "salary" type = "int"/>
</class>
</hibernate-mapping>
Наконец, мы создадим наш класс приложения с методом main () для запуска приложения, в котором мы будем использовать Criteria запросы -
import java.util.List;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;
import org.hibernate.cfg.Configuration;
public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try {
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();
/* Add few employee records in database */
Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 5000);
Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);
/* List down all the employees */
ME.listEmployees();
/* Print Total employee's count */
ME.countEmployee();
/* Print Total salary */
ME.totalSalary();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try {
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees having salary more than 2000 */
public void listEmployees( ) {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// Add restriction.
cr.add(Restrictions.gt("salary", 2000));
List employees = cr.list();
for (Iterator iterator = employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
/* Method to print total number of records */
public void countEmployee(){
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// To get total row count.
cr.setProjection(Projections.rowCount());
List rowCount = cr.list();
System.out.println("Total Coint: " + rowCount.get(0) );
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
/* Method to print sum of salaries */
public void totalSalary(){
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// To get total salary.
cr.setProjection(Projections.sum("salary"));
List totalSalary = cr.list();
System.out.println("Total Salary: " + totalSalary.get(0) );
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Компиляция и исполнение
Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем продолжить компиляцию и выполнение.
Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.
Создайте файл сопоставления Employee.hbm.xml, как показано выше.
Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.
Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.
Запустите двоичный файл ManageEmployee, чтобы запустить программу.
Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.
$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 5000
First Name: Mohd Last Name: Yasee Salary: 3000
Total Coint: 4
Total Salary: 15000
Если вы проверите свою таблицу EMPLOYEE, она должна содержать следующие записи:
mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 14 | Zara | Ali | 2000 |
| 15 | Daisy | Das | 5000 |
| 16 | John | Paul | 5000 |
| 17 | Mohd | Yasee | 3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>