1.JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。,而Hibernate是它的一种实现。除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用Jpa的一个好处是,可以更换实现而不必改动太多代码。
2.Hibernate作为JPA的一种实现,jpa的注解已经是hibernate的核心,hibernate只提供了一些补充,而不是两套注解。hibernate对jpa的支持够足量,在使用hibernate注解建议使用jpa。
使用criteria 查询简单Demo
为了更好的理解criteria 查询,考虑拥有Employee实例集合的Dept实体,Employee和Dept的元模型类的代码如下:
//All Necessary Imports
@StaticMetamodel(Dept.class)
public class Dept_ {
public static volatile SingularAttribute<Dept, Integer> id;
public static volatile ListAttribute<Dept, Employee> employeeCollection;
public static volatile SingularAttribute<Dept, String> name;
}
//All Necessary Imports
@StaticMetamodel(Employee.class)
public class Employee_ {
public static volatile SingularAttribute<Employee, Integer> id;
public static volatile SingularAttribute<Employee, Integer> age;
public static volatile SingularAttribute<Employee, String> name;
public static volatile SingularAttribute<Employee, Dept> deptId;
}
下面的代码片段展示了一个criteria 查询,它用于获取所有年龄大于24岁的员工
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24);
criteriaQuery.where(condition);
TypedQuery<Employee> typedQuery = em.createQuery(criteriaQuery);
List<Employee> result = typedQuery.getResultList();
对应的SQL: SELECT * FROM employee WHERE age > 24
构建CriteriaQuery 实例API说明
1.CriteriaBuilder 安全查询创建工厂,创建CriteriaQuery,创建查询具体具体条件Predicate 等.
CriteriaBuilder是一个工厂对象,安全查询的开始.用于构建JPA安全查询.可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder.
比如: CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
2.CriteriaQuery 安全查询主语句
CriteriaQuery对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。
它通过调用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery 获得。
CriteriaBuilder就像CriteriaQuery 的工厂一样。
CriteriaBuilder工厂类是调用EntityManager.getCriteriaBuilder 或 EntityManagerFactory.getCriteriaBuilder而得。
Employee实体的 CriteriaQuery 对象以下面的方式创建:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
3.Root 定义查询的From子句中能出现的类型
AbstractQuery是CriteriaQuery 接口的父类。它提供得到查询根的方法。
Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似。
Root实例也是类型化的,且定义了查询的FROM子句中能够出现的类型。
查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。
Criteria查询,可以有多个查询根。
Employee实体的查询根对象可以用以下的语法获得 :
Root<Employee> employee = criteriaQuery.from(Employee.class);
4.Predicate 过滤条件
过滤条件应用到SQL语句的FROM子句中。
在criteria 查询中,查询条件通过Predicate 或Expression 实例应用到CriteriaQuery 对象上。
这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。
CriteriaBuilder 也是作为Predicate 实例的工厂,Predicate 对象通过调用CriteriaBuilder 的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建。
Predicate 实例也可以用Expression 实例的 isNull, isNotNull 和 in方法获得,复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
下面的代码片段展示了Predicate 实例检查年龄大于24岁的员工实例:
Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24);
criteriaQuery.where(condition);
排序结果
Criteria查询的结果能调用CriteriaQuery.orderBy方法排序,该方法接收一个Order对象做为参数。通过调用 CriteriaBuilder.asc 或 CriteriaBuilder.Desc,Order对象能被创建。以下代码片段中,Employee实例是基于age的升序排列。
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder .createQuery(Employee.class);
Root<Employee> employee = criteriaQuery.from(Employee.class);
criteriaQuery.orderBy(criteriaBuilder.asc(employee.get(Employee_.age)));
em.createQuery(criteriaQuery).getResultList();
1.查询所有用户名
public List<String> findAllMember()
{
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteriaQuery = criteriaBuilder.createQuery(String.class);
Root<Member> member = criteriaQuery.from(Member.class);
criteriaQuery.multiselect(member.get("username"));
Predicate restrictions = criteriaBuilder.conjunction();
criteriaQuery.where(restrictions);
criteriaQuery.groupBy(member.get("username"));
TypedQuery<String> query = entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT);
return query.getResultList();
}
2.查询并排序
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Member> criteriaQuery = criteriaBuilder.createQuery(Member.class);
Root<Member> root = criteriaQuery.from(Member.class);
criteriaQuery.select(root);
Predicate restrictions = criteriaBuilder.conjunction();
if (dictSchool != null)
{
restrictions = criteriaBuilder.and(restrictions,
criteriaBuilder.equal(root.get("dictSchool"), dictSchool));
}
if (memberType != null)
{
restrictions = criteriaBuilder.and(restrictions,
criteriaBuilder.equal(root.get("memberType"), memberType));
}
criteriaQuery.where(restrictions);
criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createDate")));
return entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT).getResultList();