Hibernate - Truy vấn tiêu chí

Hibernate cung cấp các cách thay thế để thao tác các đối tượng và lần lượt dữ liệu có sẵn trong các bảng RDBMS. Một trong những phương pháp là API tiêu chí, cho phép bạn xây dựng đối tượng truy vấn tiêu chí theo chương trình, nơi bạn có thể áp dụng các quy tắc lọc và điều kiện logic.

Ngủ đông Session giao diện cung cấp createCriteria() , có thể được sử dụng để tạo Criteria đối tượng trả về các thể hiện của lớp đối tượng kiên trì khi ứng dụng của bạn thực hiện truy vấn tiêu chí.

Sau đây là ví dụ đơn giản nhất về truy vấn tiêu chí là một, sẽ chỉ trả về mọi đối tượng tương ứng với lớp Employee.

Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();

Hạn chế với Tiêu chí

Bạn có thể dùng add() phương pháp có sẵn cho Criteriađối tượng để thêm hạn chế cho truy vấn tiêu chí. Sau đây là ví dụ để thêm hạn chế trả lại hồ sơ với mức lương bằng 2000 -

Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();

Sau đây là một số ví dụ khác bao gồm các tình huống khác nhau và có thể được sử dụng theo yêu cầu -

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

Bạn có thể tạo điều kiện VÀ hoặc HOẶC bằng cách sử dụng các hạn chế của LogicalExpression như sau:

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

Mặc dù tất cả các điều kiện trên có thể được sử dụng trực tiếp với HQL như đã giải thích trong hướng dẫn trước.

Phân trang bằng cách sử dụng tiêu chí

Có hai phương pháp của giao diện Tiêu chí để phân trang.

Sr.No. Phương pháp & Mô tả
1

public Criteria setFirstResult(int firstResult)

Phương thức này nhận một số nguyên đại diện cho hàng đầu tiên trong tập kết quả của bạn, bắt đầu bằng hàng 0.

2

public Criteria setMaxResults(int maxResults)

Phương thức này yêu cầu Hibernate truy xuất một số cố định maxResults của các đối tượng.

Sử dụng hai phương pháp trên cùng nhau, chúng ta có thể tạo một thành phần phân trang trong ứng dụng web hoặc Swing của mình. Sau đây là ví dụ mà bạn có thể mở rộng để tìm nạp 10 hàng cùng một lúc -

Criteria cr = session.createCriteria(Employee.class);
cr.setFirstResult(1);
cr.setMaxResults(10);
List results = cr.list();

Sắp xếp kết quả

API tiêu chí cung cấp org.hibernate.criterion.Orderlớp để sắp xếp tập hợp kết quả của bạn theo thứ tự tăng dần hoặc giảm dần, theo một trong các thuộc tính của đối tượng của bạn. Ví dụ này minh họa cách bạn sử dụng lớp Order để sắp xếp tập hợp kết quả -

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

Dự báo & Tổng hợp

API tiêu chí cung cấp org.hibernate.criterion.Projections, có thể được sử dụng để lấy giá trị trung bình, tối đa hoặc tối thiểu của các thuộc tính. Lớp Dự báo tương tự như lớp Restrictions, ở chỗ nó cung cấp một số phương thức gốc tĩnh để lấyProjection các trường hợp.

Sau đây là một số ví dụ về các tình huống khác nhau và có thể được sử dụng theo yêu cầu -

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

Ví dụ về truy vấn tiêu chí

Hãy xem xét lớp POJO sau:

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

Hãy để chúng tôi tạo bảng NHÂN VIÊN sau để lưu trữ các đối tượng Nhân viên -

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

Sau đây sẽ là tệp ánh xạ.

<?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>

Cuối cùng, chúng tôi sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng mà chúng tôi sẽ sử dụng Criteria truy vấn -

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

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như hình trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageE Jobee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$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

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

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>