Ibernazione - Query sui criteri

Hibernate fornisce modi alternativi di manipolare gli oggetti e, a sua volta, i dati disponibili nelle tabelle RDBMS. Uno dei metodi è Criteria API, che consente di creare un oggetto query di criteri a livello di codice in cui è possibile applicare regole di filtro e condizioni logiche.

L'ibernazione Session l'interfaccia fornisce createCriteria() metodo, che può essere utilizzato per creare un file Criteria oggetto che restituisce istanze della classe dell'oggetto di persistenza quando l'applicazione esegue una query di criteri.

Di seguito è riportato l'esempio più semplice di una query di criteri è uno, che restituirà semplicemente ogni oggetto che corrisponde alla classe Employee.

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

Restrizioni con criteri

Puoi usare add() metodo disponibile per Criteriaoggetto per aggiungere restrizione per una query di criteri. Di seguito è riportato l'esempio per aggiungere una restrizione per restituire i record con lo stipendio è uguale a 2000 -

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

Di seguito sono riportati alcuni altri esempi che coprono diversi scenari e possono essere utilizzati secondo il requisito:

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

È possibile creare condizioni AND o OR utilizzando le restrizioni di LogicalExpression come segue:

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

Sebbene tutte le condizioni di cui sopra possono essere utilizzate direttamente con HQL come spiegato nel tutorial precedente.

Impaginazione utilizzando criteri

Esistono due metodi dell'interfaccia Criteria per l'impaginazione.

Sr.No. Metodo e descrizione
1

public Criteria setFirstResult(int firstResult)

Questo metodo accetta un numero intero che rappresenta la prima riga del set di risultati, a partire dalla riga 0.

2

public Criteria setMaxResults(int maxResults)

Questo metodo dice a Hibernate di recuperare un numero fisso maxResults di oggetti.

Usando insieme i due metodi precedenti, possiamo costruire un componente di paging nella nostra applicazione web o Swing. Di seguito è riportato l'esempio, che puoi estendere per recuperare 10 righe alla volta:

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

Ordinamento dei risultati

L'API Criteria fornisce l'estensione org.hibernate.criterion.Orderclass per ordinare il set di risultati in ordine crescente o decrescente, in base a una delle proprietà dell'oggetto. Questo esempio dimostra come useresti la classe Order per ordinare il set di risultati:

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

Proiezioni e aggregazioni

L'API Criteria fornisce l'estensione org.hibernate.criterion.Projectionsclass, che può essere utilizzato per ottenere la media, il massimo o il minimo dei valori di proprietà. La classe Projections è simile alla classe Restrictions, in quanto fornisce diversi metodi factory statici per ottenereProjection istanze.

Di seguito sono riportati alcuni esempi che coprono diversi scenari e possono essere utilizzati secondo i requisiti:

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

Esempio di query sui criteri

Considera la seguente classe 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;
   }
}

Creiamo la seguente tabella EMPLOYEE per memorizzare gli oggetti 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)
);

Di seguito sarà il file di mappatura.

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

Infine, creeremo la nostra classe applicativa con il metodo main () per eseguire l'applicazione che useremo Criteria domande -

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

Compilazione ed esecuzione

Ecco i passaggi per compilare ed eseguire l'applicazione sopra menzionata. Assicurati di aver impostato PATH e CLASSPATH in modo appropriato prima di procedere per la compilazione e l'esecuzione.

  • Creare il file di configurazione hibernate.cfg.xml come spiegato nel capitolo sulla configurazione.

  • Crea il file di mappatura Employee.hbm.xml come mostrato sopra.

  • Crea il file sorgente Employee.java come mostrato sopra e compilarlo.

  • Crea il file sorgente ManageEmployee.java come mostrato sopra e compilarlo.

  • Esegui il binario ManageEmployee per eseguire il programma.

Si otterrebbe il seguente risultato e i record verranno creati nella tabella 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

Se controlli la tua tabella EMPLOYEE, dovrebbe avere i seguenti record:

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>