返回介绍

4.2 传统方式

发布于 2025-04-22 19:57:18 字数 1387 浏览 0 评论 0 收藏

在开始之前,首先看一下 Spring Data 如何为领域模型实现数据访问层,并讨论如何按照传统的方式实现数据访问层。在示例项目中会找到示例的实现和客户端都使用了一些额外的注解如 @Profile(对于实现)和 @ActiveProfile(对于测试用例)。因为 Spring Data Repository 方式会创建一个 CustomerRepository 实例,并且我们还有一个为手动实现所创建的实例。因此,这里使用了 Spring 的 Profile 机制,只对单一的测试用例启动传统的实现方式。我们并没有在这里的实例代码中展示这些注解,因为如果按照传统的方式来实现整个数据访问层的话,它们实际上并不会被用到。

为了使用普通的 JPA 来持久化前述的实体,现在要创建一个接口以及针对我们存储的实现,如示例 4-8 所示。

示例 4-8 为 Customer 定义的存储接口

c0408

这样,我们定义了一个 save(…) 方法来存储账号以及根据电子邮件地址查找所有账号的查询方法。现在看一下如果基于普通 JPA 实现的话,存储的实现类会是什么样子,如示例 4-9 所示。

示例 4-9 对于 Customer 的传统存储实现

c0409

实现类中使用了 JPA 的 EntityManager,因为设置了 JPA 的 @PersistenceContext 注解,因此它将会通过 Spring 容器注入进来。这个类设置了 @Repository 注解,因此会将 JPA 的异常转换为 Spring 的 DataAccessException 异常体系。除此之外,我们使用了 @Transactional 注解,从而保证 save(...) 操作运行在事务之中,并且还允许为 findByEmailAddress(...) 设置 readOnly 标志(在类级别)。这有助于在持久化厂商内部以及数据库级别对性能进行优化。

因为我们不想让客户端来决定该调用 EntityManager 的 merge(...) 方法还是 persist(...) 方法,所以我们使用 Customer 的 id 域来判断某一个 Customer 对象是不是新建的。当然,这个逻辑可以抽取到一个通用的存储超类之中,因为我们可能不希望对每一个特定的领域对象存储实现都重复这段代码。查询方法也很简单直接:我们创建 Query、绑定参数并执行查询获取结果。它的实现非常简单,你甚至可以将实现代码视为样板。稍微想象一下,我们可以根据方法签名衍生出实现:想要获得单个 Customer、查询与方法的名字很接近,并且只需将方法参数绑定给它。所以,正如你所看到的,这里有提升的空间。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。