- 内容提要
- 序
- 前言
- 第一部分 背景知识
- 第 1 章 Spring Data 项目
- 第 2 章 Repository:便利的数据访问层
- 第 3 章 使用 Querydsl 实现类型安全的查询
- 第二部分 关系型数据库
- 第 4 章 JPA Repository
- 第 5 章 借助 Querydsl SQL 实现类型安全的 JDBC 编程
- 第三部分 NoSQL
- 第 6 章 MongoDB: 文档存储
- 第 7 章 Neo4j:图数据库
- 第 8 章 Redis:键/值存储
- 第四部分 快速应用开发
- 第 9 章 使用 Spring Roo 实现持久层
- 第 10 章 REST Repository 导出器
- 第五部分 大数据
- 第 11 章 Spring for Apache Hadoop
- 第 12 章 使用 Hadoop 分析数据
- 第 13 章 使用 Spring Batch 和 Spring Integration 创建大数据管道
- 第六部分 数据网格
- 第 14 章 分布式数据网格:GemFire
- 关于封面
3.1 Querydsl 简介
当使用 Querydsl 的时候,通常开始会从领域类中衍生出元模型。尽管这个类库也可以使用简单的字符串文本,但创建元模型会释放出 Querydsl 的全部能量,尤其是在属性的类型安全以及关键字引用方面。衍生机制基于 Java 6 的注解处理工具(Annotation Processing Tool,APT),它能够挂接到编译器中并对源码甚至编译后的类进行处理。想了解更多信息的话,可参阅 3.2 小节“生成查询模型”。开始之前,需要定义一个领域类,如示例 3-1 所示。我们使用几个原始类型和非原始类型的属性来为 Customer 建模。
示例 3-1 Customer 领域类
注意我们为这个类使用了 @QueryEntity 注解。这是默认的注解,Querydsl 注解处理器将会使用它来生成相关的查询对象。在与特定的存储集成使用的时候,APT 处理器能够识别出特定存储的实体(如对于 JPA 所使用的就是 @Entity)并使用它们来衍生查询类。在这个简介部分,我们不会与存储一起工作,所以无法使用特定存储的映射注解,只是使用 @QueryEntity 而已。生成的 Querydsl 查询类如示例 3-2 所示。
示例 3-2 Querydsl 生成的查询类
可以在该模块示例工程的 target/generated-sources/queries 目录下找到这些类。该类暴露了公开的 Path 属性以及对其他查询类的引用(如 QEmailAddress)。在定义断言(predicate)的时候,IDE 就能在代码补全时列出所有可用的 Path。可以使用这些 Path 表达式来定义可重用的断言,如示例 3-3 所示。
示例 3-3 使用查询类来定义断言
将静态的 QCustomer.customer 实例赋值给 customer 变量,这样就能非常简洁地引用它的 Path 属性。可以看到,断言的定义非常简单整洁,而且──最重要的就是──类型安全。变更领域类将会重新生成查询模型。变更所导致的属性引用失效将会产生编译错误,从而提示我们要进行修改的地方。对于每种 Path 类型所能使用的方法也会考虑到 Path 的类型(如 like(…) 方法就只能对 String 属性有意义,因此只会提供给这种类型使用)。
因为断言的定义非常简洁,所以它们能够很容易地用在方法声明的内部。另一方面,我们可以很容易地以可重用的方式来定义断言,定义原子性的断言并通过像 And 或 Or 这样的操作符将其连接起来以形成复杂的断言(如示例 3-4 所示)。
示例 3-4 连接原子性的断言
我们可以使用刚刚编写的断言来为特定的存储或者简单的集合来编写查询。鉴于对特定存储的查询执行主要会通过 Spring Data Repository 抽象来实现(见 3.3 小节“与 Spring Data Repository 集成”),所以作为例子,为了简单起见,我们会使用这个特性来对集合进行查询。首先,构建各种类型的 Product,这样我们就有东西可以过滤了,如示例 3-5 所示。
示例 3-5 构建 Product
接下来,我们可以使用 Querydsl 来对这个集合建立查询,也就是对其建立某种类型的过滤器(如示例 3-6 所示)。
示例 3-6 使用 Querydsl 断言过滤 Product
我们使用 from(...) 方法来建立 Querydsl 查询,它是 querydsl-collections 模块之中 MiniAPI 类的一个静态方法。我们将 Product 的查询类实例以及作为源的集合传递给它。现在,我们就可以使用 where(...) 方法将断言应用于源列表之上并使用某一个 list(...) 方法(如示例 3-7 所示)执行查询。在我们的场景下,只是简单地返回那些匹配预先定义断言的 Product。将$.description 传递给 list(…) 方法后,我们就能将结果投射(project)到 Product 的名称上,因此返回一个 String 的集合。
示例 3-7 使用 Querydsl 断言过滤 Product(投射)
借助于 Querydsl,我们能够以一种简洁和便利的方式来定义实体断言。它们可以基于各种存储以及 Java 类的映射信息而产生。Querydsl 的 API 以及它所支持的存储方式使得我们可以产生断言,并以此来定义查询。相同的 API 也可以用于对 Java 集合进行过滤。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论