标准是用来定义查询实体的预定义API。它是定义JPQL查询的另一种方式。这些查询是类型安全的,可移植的,并且容易被改变的语法进行修改。类似于JPQL,它遵循的抽象模式(容易编辑模式)和嵌入的对象。元数据API是夹杂着标准的API模型持久性实体的标准查询。
标准的API的主要优点是,错误可以较早在编译时被检测到。基于字符串JPQL查询和基于查询JPA的范围是在性能和效率相同。
标准API历史
该标准被纳入因此标准的每一步中JPA的规范通知所有版本JPA。
- 在JPA2.0中,标准查询API,查询的标准化开发。
- 在JPA2.1,标准更新和删除(批量更新和删除)都包括在内。
标准查询结构
该标准与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.form方法被调用来设置查询根。
- CriteriaQuery.select被调用来设置结果列表类型。
- TypedQuery<T>实例是用来准备一个查询执行和指定的查询结果的类型。
- 在TypedQuery<T>对象getResultList方法来执行查询。该查询返回实体的集合,结果存储在一个列表中。
标准API示例
让我们考虑 employee 数据库的例子。让我们假定该 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.yiibai.eclipselink.entity
创建一个名为Employee.java类。Employee实体如下图所示:
package com.yiibai.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 文件的内容如下:
<?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.yiibai.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>
服务类
该模块包含服务类,它实现了使用元数据API的初始化条件查询的一部分。创建一个名为“com.yiibai.eclipselink.service'包。在这个包下创建一个类CriteriaAPI.java。在DAO类如下所示:
package com.yiibai.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.yiibai.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 =criteriaQuery.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