天天看点

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

本节书摘来自异步社区《spring data实战》一书中的第2章,第2.1节,作者: 【美】mark pollack , oliver gierke , thomas risberg , jon brisbin , michael hunger著,更多章节内容可以访问云栖社区“异步社区”公众号查看

长期以来,实现应用程序的数据访问层一直是件繁琐的工作,因为我们经常需要编写大量的样板式代码,而且贫血(anemic)的领域类并没有按照真正面向对象或领域驱动方式来进行设计。因此spring data repository抽象的目标就是大幅简化各种持久化存储持久层的实现。我们将会使用spring data jpa模块作为例子来讨论repository抽象的基本理念。对于其他类型的存储,可以参考对应的例子。

我们选取领域模型中的customer领域类,它会被持久化到任意的存储之中。这个类应该如示例2-1所示。

示例2-1 customer领域类

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

传统的实现数据访问层的方式至少需要实现一个存储类(repository class),这个类会包含基本的crud(create、read、update与delete)方法以及通过限制条件来访问实体子集的查询方法。spring data repository的方式能够避免大多数的代码,只需为这个实体存储声明简单的接口定义即可,如示例2-2所示。

示例2-2 customerrepository接口定义

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

正如你所见,我们扩展了spring data的repository接口,它是通用的标识接口。它的主要职责是让spring data的基础设施识别出所有用户定义的spring data repository。除此之外,它还会捕获托管的领域类以及实体的id类型,稍后这些功能会提供很大的便利性。为了能够自动发现所声明的接口,可以使用存储特定的xml命名空间中的元素(如示例2-3所示),或是在使用javaconfig时借助相关的@enable...repositories注解(如示例2-4所示)。在示例中会使用jpa。我们只需将xml元素的base-package属性配置为我们的根包(root package),spring data会扫描它来查找repository接口。如果没有给出更进一步的配置,那么它只会简单地检查包中带有注解的类。

示例2-3 使用xml激活spring data repository

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

示例2-4 使用java config激活spring data repository

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

xml和javaconfig配置都需要添加存储专用的bean声明来进行完善,如jpa的entitymanagerfactory以及datasource等。对于其他形式的存储,我们只需使用对应的命名空间元素或注解即可。例如,示例2-5所示的配置片段,将会找到spring data repository并创建spring bean,这些bean实际上是由一组实现了所发现接口的代理所组成的。因此,现在可以继续编写客户端,通过spring的自动装配就能访问这个bean了。

customerrepository接口建立之后,我们就可以继续深入学习并添加一些易于声明的查询方法。常见的需求是通过电子邮件地址来获取customer。为了做到这一点,我们添加合适的查询方法,如示例2-6所示。

示例2-5 客户端使用spring data repository

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

示例2-6 声明查询方法

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门

命名空间元素将会在容器启动的时候扫描到这个接口并触发spring data的基础设施为其创建spring bean。基础设施会探查接口中声明的方法并确定方法调用时要执行的查询。如果只是这样简单地定义方法的话,那么spring data将会根据其名字衍生出一个查询。在定义查询方面还有其他的途径可选,可以阅读2.2小节“定义查询方法”来了解更多信息。

在示例2-6中,由于我们遵循了领域对象属性的命名约定,因而查询可以衍生得到。查询方法名中的emailaddress部分其实就对应了customer类的emailaddress属性,因此,在使用jpa模块时,spring data会自动为声明的方法衍生出select c from customer c where c.emailaddress = ?1。它还会检查方法声明中属性引用的合法性,如果发现任何错误则会在容器启动时,出现启动失败。现在,客户端可以很容易地执行这个方法,给定的方法参数会绑定到根据方法名衍生出来的查询之中并且执行该查询,如示例2-7所示。

示例2-7 执行查询方法

《Spring Data实战》——第2章 Repository:便利的数据访问层 2.1快速入门