JPA Criteria API


Criteria API是用于定义实体查询的预定义API。这是定义JPQL查询的另一种方法。这些查询是类型安全的,并且通过更改语法来移植并且易于修改。与JPQL类似,它遵循抽象模式(易于编辑模式)和嵌入对象。元数据API与标准API混合以为标准查询建立持久实体。

标准API的主要优点是可以在编译时更早地检测到错误。基于字符串的JPQL查询和基于JPA标准的查询在性能和效率方面相同。

标准API的历史

标准API包含在JPA的所有版本中,因此标准API的每个步骤都通过JPA的规范进行通知。

  • 在JPA 2.0中,标准查询API开发了查询标准化。
  • 在JPA 2.1中,包括了条件更新和删除(批量更新和删除)。

标准查询结构

Criteria API和JPQL密切相关,允许在他们的查询中使用类似的操作符进行设计。它遵循javax.persistence.criteria包来设计查询。查询结构意味着语法标准查询。

以下简单条件查询将返回数据源中实体类的所有实例。

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();

CriteriaQuery<Entity class> cq = cb.createQuery(Entity.class);
Root<Entity> from = cq.from(Entity.class);

cq.select(Entity);
TypedQuery<Entity> q = em.createQuery(cq);
List<Entity> allitems = q.getResultList();

该查询演示了创建条件的基本步骤。

  • EntityManager实例用于创建CriteriaBuilder对象。
  • CriteriaQuery实例用于创建查询对象。该查询对象的属性将随查询的细节而被修改。
  • 调用CriteriaQuery.from方法来设置查询根。
  • 调用CriteriaQuery.select来设置结果列表类型。
  • TypedQuery 实例用于准备执行查询并指定查询结果的类型。
  • TypedQuery 对象上的getResultList方法执行查询。该查询返回实体的集合,结果存储在List中。

标准API的示例

让我们考虑雇员数据库的例子。让我们假设jpadb.employee表包含以下记录:

Eid Ename           Salary  Deg
401 Gopal           40000   Technical Manager
402 Manisha         40000   Proof reader
403 Masthanvali     35000   Technical Writer
404     Satish          30000   Technical writer
405 Krishna         30000   Technical Writer
406 Kiran           35000   Proof reader

在名为 JPA_Eclipselink_Criteria 的eclipse IDE中创建一个JPA项目。该项目的所有模块如下所示:

创建实体

'src' 包下创建一个名为 com.CodingDict.eclipselink.entity 包。

在给定的包下创建一个名为 Employee.java 的类。Employee类实体显示如下:

package com.CodingDict.eclipselink.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employee {
   @Id
   @GeneratedValue(strategy= GenerationType.AUTO)   

   private int eid;
   private String ename;
   private double salary;
   private String deg;

   public Employee(int eid, String ename, double salary, String deg) {
      super( );
      this.eid = eid;
      this.ename = ename;
      this.salary = salary;
      this.deg = deg;
   }

   public Employee( ) {
      super();
   }

   public int getEid( ) {
      return eid;
   }

   public void setEid(int eid) {
      this.eid = eid;
   }

   public String getEname( ) {
      return ename;
   }

   public void setEname(String ename) {
      this.ename = ename;
   }

   public double getSalary( ) {
      return salary;
   }

   public void setSalary(double salary) {
      this.salary = salary;
   }

   public String getDeg( ) {
      return deg;
   }

   public void setDeg(String deg) {
      this.deg = deg;
   }

   @Override
   public String toString() {
   return "Employee [eid = " + eid + ", ename = " + ename + ", salary = " + salary + ", deg = " + deg + "]";
   }
}

persistence.xml中

需要Persistence.xml文件来配置数据库和实体类的注册。

在创建JPA项目的同时,eclipse IDE将创建Persistence.xml。配置细节是用户规格。persistence.xml文件如下所示:

<?xml version = "1.0" encoding = "UTF-8"?>
<persistence version="2.0" xmlns = "http://java.sun.com/xml/ns/persistence"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/persistence
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

   <persistence-unit name = "Eclipselink_JPA" transaction-type = "RESOURCE_LOCAL">
      <class>com.CodingDict.eclipselink.entity.Employee</class>

      <properties>
         <property name = "javax.persistence.jdbc.url" value = "jdbc:mysql://localhost:3306/jpadb"/>
         <property name = "javax.persistence.jdbc.user" value = "root"/>
         <property name = "javax.persistence.jdbc.password" value = "root"/>
         <property name = "javax.persistence.jdbc.driver"
         value="com.mysql.jdbc.Driver"/>
         <property name = "eclipselink.logging.level" value = "FINE"/>
         <property name = "eclipselink.ddl-generation"
         value="create-tables"/>
      </properties>

   </persistence-unit>
</persistence>

服务类

此模块包含服务类,它使用MetaData API初始化实现Criteria查询部分。创建一个名为 'com.CodingDict.eclipselink.service' 的包。名为 CriteriaAPI.java 的类是在给定的包下创建的。DAO类显示如下:

package com.CodingDict.eclipselink.service;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import com.CodingDict.eclipselink.entity.Employee;

public class CriteriaApi {
   public static void main(String[] args) {

   EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
   EntityManager entitymanager = emfactory.createEntityManager( );
   CriteriaBuilder criteriaBuilder = entitymanager.getCriteriaBuilder();
   CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
   Root<Employee> from = criteriaQuery.from(Employee.class);

   //select all records
   System.out.println(Select all records);
   CriteriaQuery<Object> select = c riteriaQuery.select(from);
   TypedQuery<Object> typedQuery = entitymanager.createQuery(select);
   List<Object> resultlist = typedQuery.getResultList();

   for(Object o:resultlist) {
      Employee e = (Employee)o;
      System.out.println("EID : " + e.getEid() + " Ename : " + e.getEname());
   }

   //Ordering the records
   System.out.println(Select all records by follow ordering);
   CriteriaQuery<Object> select1 = criteriaQuery.select(from);
   select1.orderBy(criteriaBuilder.asc(from.get("ename")));
   TypedQuery<Object> typedQuery1 = entitymanager.createQuery(select);
   List<Object> resultlist1 = typedQuery1.getResultList();

   for(Object o:resultlist1){
      Employee e=(Employee)o;
      System.out.println("EID : " + e.getEid() + " Ename : " + e.getEname());
   }

   entitymanager.close( );
   emfactory.close( );
   }
}

在编译和执行上述程序之后,您将在Eclipse IDE的控制台面板中获得输出,如下所示:

Select All records
EID : 401 Ename : Gopal
EID : 402 Ename : Manisha
EID : 403 Ename : Masthanvali
EID : 404 Ename : Satish
EID : 405 Ename : Krishna
EID : 406 Ename : Kiran
Select All records by follow Ordering
EID : 401 Ename : Gopal
EID : 406 Ename : Kiran
EID : 405 Ename : Krishna
EID : 402 Ename : Manisha
EID : 403 Ename : Masthanvali
EID : 404 Ename : Satish