博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java-jpa-criteriaBuilder使用入门
阅读量:3921 次
发布时间:2019-05-23

本文共 4811 字,大约阅读时间需要 16 分钟。

项目中使用jpa ,第一次见查询起来一脸蒙,这就去查下jpa查询的方式,和概念。

 

 

jpa


概念 

创建使用Java Persistence API的存储库是一个繁琐的过程,需要大量时间并需要大量样板代码。一种推荐的方式是使用

元模型

概念 

在JPA中,标准查询是以元模型的概念为基础的,元模型是为具体持久化单元的受管实体定义的.这些实体可以是实体类,嵌入类或者映射的父类.提供受管实体元信息的类就是元模型类. 
简单的说就是元模型是实体类对应的一个“受管实体 
举个例子: 
实体类 Employee(com.demo.entities包中定义)

@Entity@Tablepublic class Employee{ private int id; private String name; private int age; @OneToMany private List
addresses; // Other code… }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Employee类的标准元模型类的名字是 Employee_

import javax.annotation.Generated;import javax.persistence.metamodel.SingularAttribute;import javax.persistence.metamodel.ListAttribute;import javax.persistence.metamodel.StaticMetamodel;@StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute
id; public static volatile SingularAttribute
age; public static volatile SingularAttribute
name; public static volatile ListAttribute
addresses; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Employee的每一个属性都会使用在JPA2规范中描述的以下规则在相应的元模型类中映射:

  • 元模型类的属性全部是static和public的。
  • 元模型类的属性全部是static和public的。Employee的每一个属性都会使用在JPA2规范中描述的以下规则在相应的元模型类中映射:

  • 对于Addess这样的集合类型,会定义静态属性ListAttribute< A, B> b,这里List对象b是定义在类A中类型B的对象。其它集合类型可以是SetAttribute, MapAttribute 或 CollectionAttribute 类型。

看到这应该会有个疑问,这麻烦,为什么要使用这个元模型?有啥好处? 

好处肯定是有的,毕竟是标准jpa定义的东西。我这网上查了下,好处很多:

  • 查询更加类型安全

好吧,我暂时就查到这个。

criteria 查询

为了更好的理解criteria 查询,考虑拥有Employee实例集合的Dept实体,Employee和Dept的元模型类的代码如下:

//All Necessary Imports@StaticMetamodel(Dept.class)public class Dept_ {        public static volatile SingularAttribute
id; public static volatile ListAttribute
employeeCollection; public static volatile SingularAttribute
name; } //All Necessary Imports @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute
id; public static volatile SingularAttribute
age; public static volatile SingularAttribute
name; public static volatile SingularAttribute
deptId; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

下面的代码片段展示了一个criteria 查询,它用于获取所有年龄大于24岁的员工:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();CriteriaQuery
criteriaQuery = criteriaBuilder.createQuery(Employee.class); Root
employee = criteriaQuery.from(Employee.class); Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24); criteriaQuery.where(condition); TypedQuery
typedQuery = em.createQuery(criteriaQuery); List
result = typedQuery.getResultList();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

对应的SQL: SELECT * FROM employee WHERE age > 24

CriteriaBuilder 安全查询创建工厂

CriteriaBuilder 安全查询创建工厂,,创建CriteriaQuery,创建查询具体具体条件Predicate 等。 

CriteriaBuilder是一个工厂对象,安全查询的开始.用于构建JPA安全查询.可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder。 
比如: 
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery 安全查询主语句

  • 它通过调用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery 获得。
  • CriteriaBuilder就像CriteriaQuery 的工厂一样。
  • CriteriaQuery对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。
  • Employee实体的 CriteriaQuery 对象以下面的方式创建:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();CriteriaQuery
criteriaQuery = criteriaBuilder.createQuery(Employee.class);
  • 1
  • 2

Root

  • Root 定义查询的From子句中能出现的类型
  • Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似。
  • Root实例也是类型化的,且定义了查询的FROM子句中能够出现的类型。
  • 查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。
  • Criteria查询,可以有多个查询根。
  • Employee实体的查询根对象可以用以下的语法获得 :
Root
employee = criteriaQuery.from(Employee.class);
  • 1

Predicate 过滤条件

  • 过滤条件应用到SQL语句的FROM子句中。
  • 在criteria 查询中,查询条件通过Predicate 或Expression 实例应用到CriteriaQuery 对象上。
  • 这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。
  • Predicate 实例也可以用Expression 实例的 isNull, isNotNull 和 in方法获得,复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
  • CriteriaBuilder 也是作为Predicate 实例的工厂,Predicate 对象通过调用CriteriaBuilder 的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建。
  • 这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。
  • 下面的代码片段展示了Predicate 实例检查年龄大于24岁的员工实例:
Predicate condition = criteriaBuilder.gt(employee.get(Employee_.age), 24); criteriaQuery.where(condition);
  • 1
  • 2

过Employee_元模型类age属性,称之为路径表达式。若age属性与String文本比较,编译器会抛出错误,这在JPQL中是不可能的。这就是元模型的作用吗??

Predicate[] 多个过滤条件

List
predicatesList = new ArrayList
();

predicatesList.add(…Pridicate.)

criteriaQuery.where(predicatesList.toArray(new Predicate[predicatesList.size()]));

OR语句(可怕)
predicatesList.add(criteriaBuilder.or(criteriaBuilder.equal(root.get(RepairOrder_.localRepairStatus), LocalRepairStatus.repairing),criteriaBuilder.equal(root.get(RepairOrder_.localRepairStatus), LocalRepairStatus.diagnos)));
忽略大小写(全大写)
predicatesList.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(RepairShop_.shopName)), StringUtils.upperCase(StringUtils.trim(this.shopName)) + “%”));

引用原文:

转载地址:http://wuern.baihongyu.com/

你可能感兴趣的文章
从内存中释放Selenium chromedriver.exe
查看>>
如何在 C# 中使用 MSMQ
查看>>
小试elsa
查看>>
巧用 Lazy 解决.NET Core中的循环依赖关系
查看>>
微前端架构在容器平台的应用
查看>>
C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项
查看>>
仓储模式到底是不是反模式?
查看>>
ABP vNext分布式事件总线RabbitMQ注意事项
查看>>
【One by One系列】IdentityServer4(一)OAuth2.0与OpenID Connect 1.0
查看>>
为什么人和人的差距这么大?
查看>>
ML.NET 推荐引擎中一类矩阵因子分解的缺陷
查看>>
微软2020开源回顾:止不住的挨骂,停不下的贡献
查看>>
说说 RabbiMQ 的应答模式
查看>>
OpenTelemetry - 云原生下可观测性的新标准
查看>>
使用 ML.NET 实现峰值检测来排查异常
查看>>
通过 .NET NativeAOT 实现用户体验升级
查看>>
如何友好的处理 WebApi 中抛出的错误
查看>>
因MemoryCache闹了个笑话
查看>>
Dotnet的垃圾回收
查看>>
乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时
查看>>