- 内容提要
- 序
- 前言
- 第一部分 背景知识
- 第 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
- 关于封面
4.2 传统方式
在开始之前,首先看一下 Spring Data 如何为领域模型实现数据访问层,并讨论如何按照传统的方式实现数据访问层。在示例项目中会找到示例的实现和客户端都使用了一些额外的注解如 @Profile(对于实现)和 @ActiveProfile(对于测试用例)。因为 Spring Data Repository 方式会创建一个 CustomerRepository 实例,并且我们还有一个为手动实现所创建的实例。因此,这里使用了 Spring 的 Profile 机制,只对单一的测试用例启动传统的实现方式。我们并没有在这里的实例代码中展示这些注解,因为如果按照传统的方式来实现整个数据访问层的话,它们实际上并不会被用到。
为了使用普通的 JPA 来持久化前述的实体,现在要创建一个接口以及针对我们存储的实现,如示例 4-8 所示。
示例 4-8 为 Customer 定义的存储接口
这样,我们定义了一个 save(…) 方法来存储账号以及根据电子邮件地址查找所有账号的查询方法。现在看一下如果基于普通 JPA 实现的话,存储的实现类会是什么样子,如示例 4-9 所示。
示例 4-9 对于 Customer 的传统存储实现
实现类中使用了 JPA 的 EntityManager,因为设置了 JPA 的 @PersistenceContext 注解,因此它将会通过 Spring 容器注入进来。这个类设置了 @Repository 注解,因此会将 JPA 的异常转换为 Spring 的 DataAccessException 异常体系。除此之外,我们使用了 @Transactional 注解,从而保证 save(...) 操作运行在事务之中,并且还允许为 findByEmailAddress(...) 设置 readOnly 标志(在类级别)。这有助于在持久化厂商内部以及数据库级别对性能进行优化。
因为我们不想让客户端来决定该调用 EntityManager 的 merge(...) 方法还是 persist(...) 方法,所以我们使用 Customer 的 id 域来判断某一个 Customer 对象是不是新建的。当然,这个逻辑可以抽取到一个通用的存储超类之中,因为我们可能不希望对每一个特定的领域对象存储实现都重复这段代码。查询方法也很简单直接:我们创建 Query、绑定参数并执行查询获取结果。它的实现非常简单,你甚至可以将实现代码视为样板。稍微想象一下,我们可以根据方法签名衍生出实现:想要获得单个 Customer、查询与方法的名字很接近,并且只需将方法参数绑定给它。所以,正如你所看到的,这里有提升的空间。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论