zl程序教程

您现在的位置是:首页 >  后端

当前栏目

《Spring Data实战》——2.3 定义Repository

Spring 实战 定义 Data 2.3 Repository
2023-09-11 14:17:33 时间

本节书摘来自异步社区《Spring Data实战》一书中的第2章,第2.3节,作者: 【美】Mark Pollack , Oliver Gierke , Thomas Risberg , Jon Brisbin , Michael Hunger著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.3 定义Repository

到目前为止,我们看到了带有查询方法的Repository接口,这些查询有的是从方法名中衍生出来的,有的是手动声明的,这取决于Spring Data为实际存储类型所提供的使用方式。为了衍生出这些查询,我们必须扩展Spring Data的特定标识接口:Repository。除了查询以外,在你的Repository中还需要一些其他的功能:存储对象,删除对象,根据ID进行查找,返回所有存储的实体或按页对它们进行访问。通过Repository接口来暴露这些功能的最简单方式就是使用一个Spring Data所提供的更为高级的Repository接口。

Repository

一个简单的标识接口,允许Spring Data的基础设施获取用户定义的Repository。

CrudRepository

扩展自Repository并添加了基本的持久化方法如对实体的保存、查找以及删除。

PagingAndSortingRepositories

扩展自CrudRepository并添加了按页访问实体以及根据给定的条件(criteria)进行排序的方法。

假设我们想让CustomerRepository暴露基本的CRUD方法,所需要做就是修改其声明,如示例2-12所示。

示例2-12 暴露CRUD方法的CustomerRepository

screenshot

CrudRepository接口如示例2-13所示。它包括了保存单个实体以及多个Iterable实体的方法、获取单个实体或所有实体的方法以及不同形式的delete(...)方法。

示例2-13 CrudRepository

screenshot

支持Repository方式的每个Spring Data模块都提供了这个接口的实现。因此,我们声明的命名空间元素会触发基础设施,这些设施不仅会启动那些用于执行查询方法的合适代码,同时还会使用一个通用Repository实现类的实例来在背后执行CrudRepository中所声明的方法,最终会将save(...)、findAll()等方法的调用委托给该实例。PagingAndSortingRepository(如示例2-14所示)扩展了CrudRepository并为通用的findAll(...)添加了处理Pageable和Sort实例的方法,从而能够实现逐页访问实体。

示例2-14 PagingAndSortingRepository

screenshot

要将这些功能引入到CustomerRepository中,只需简单地扩展PagingAndSorting Repository来取代CrudRepository即可。

2.3.1 调整Repository接口
正如我们在前面所见,通过扩展合适的Spring Data接口,可以很容易地引入大量预先定义的功能。这种级别的粒度实际上是一种权衡,那就是如果为所有的查找方法、所有的保存方法等都定义单独的接口,我们会暴露接口的数量(以及因此导致的复杂性)以及开发人员使用的便利性之间的权衡。

但是,可能会有这样的场景,那就是只想暴露读方法(CRUD中的R)或者只想在Repository接口中将删除方法屏蔽掉。如今,Spring Data允许定义个性化的基础Repository,只需按照以下的步骤操作即可。

1.创建一个接口,这个接口要么扩展自Repository,要么添加@RepositoryDefinition注解。

2.添加想要暴露的方法并确保它们与Spring Data基础Repository接口所提供的方法签名相同。

3.对于实体所对应的接口声明,要使用这个接口作为基础接口。

为了阐述这一点,假设我们只想暴露接收Pageable的findAll(...)方法以及save方法。这个基础接口看起来可能如示例2-15所示。

示例2-15 自定义基础Repository接口

screenshot

需要注意的一点是我们为这个接口添加了一个额外的注解@NoRepositoryBean,从而确保Spring Data Repository的基础设施不会试图为其创建Bean的实例。让CustomerRepository扩展这个接口就能精确做到只暴露你所定义的API。

接下来可以定义出各种基本的接口(如ReadOnlyRepository或SaveOnlyRepository)甚至组成它们的继承体系,这取决于项目的需要。通常建议本地定义的CRUD方法在开始的时候直接位于每个实体的具体Repository中,必要的话,再将它们要么转移到Spring Data提供的基础Repository中,要么转移到特制的Repository中。按照这种方式,可以保证随着项目复杂性的增长,构件(artifact)的数量能够自然地增长。

2.3.2 手动实现Repository方法
到目前为止,看到了两种类型的Repository方法:CRUD方法和查询方法。每种类型都是由Spring Data的基础设施实现的,要么通过背后的实现类,要么通过查询执行引擎。当构建应用程序的时候,这两种场景可能会覆盖你所面临的很大范围的数据访问操作。但是,有些场景需要手动实现代码。现在,让我们看一下如何做到这一点。

我们开始只实现那些需要手动实现的功能并在实现类中遵循一些命名的约定,如示例2-16所示。

示例2-16 为Repository实现自定义功能

screenshot

接口和实现类均不需要了解Spring Data的任何事情。它与使用Spring手动实现代码非常类似。按照Spring Data来看,这个代码片段最有意思的地方在于实现类的名字遵循了命名的约定,也就是在核心Repository接口(在我们的场景中就是CustomerRepository)的名字上加Impl后缀。同时需要注意,我们将接口和实现类都设为包内私有(package private),从而阻止从包外访问它们。

最后一步是修改初始Repository接口的声明,使其扩展刚刚引入的接口,如示例2-17所示。

示例2-17 在CustomerRepository中包含自定义功能

screenshot

现在,我们已经将CustomerRepositoryCustom暴露的API引入到CustomerRepository之中了,这会使其成为Customer数据访问API的中心点。客户端代码现在就可以调用CustomerRepository.myCustomMethod(...)了。但是,这个实现类会如何被发现并置于最终执行的代理之中的呢?实际上,Repository的启动过程看起来是这样的。

1.发现repository接口(如CustomerRepository)。

2.尝试寻找一个Bean定义,这个Bean的名字为接口的小写形式并添加Impl后缀(如customerRepositoryImpl)。如果能够找到,就使用它。

3.如果没有找到,我们会扫描寻找一个类,这个类的名字为核心Repository接口的名字并添加Impl后缀(例如,在这个例子中CustomerRepositoryImpl会被找到)。如果找到了这样的类,那么将其注册为Spring Bean并使用它。

4.找到的自定义实现类将会装配到被发现接口的代理配置之中并且在方法调用时会作为潜在的目标类。

这种机制可以很容易地为特定Repository实现自定义代码。用于进行实现查找的后缀可以在XML命名空间中或启用Repository的注解属性中(查看各种存储相关的章节来了解更多)进行个性化设置。


【深入浅出Spring原理及实战】「源码调试分析」深入源码探索Spring底层框架的的refresh方法所出现的问题和异常 1. 阅读Spring官方文档,了解Spring框架的基本概念和使用方法。 2. 下载Spring源码,可以从官网或者GitHub上获取。 3. 阅读Spring源码的入口类,了解Spring框架的启动过程和核心组件的加载顺序。 4. 阅读Spring源码中的注释和文档,了解每个类和方法的作用和用法。 5. 调试Spring源码,可以通过IDEA等工具进行调试,了解Spring框架的内部实现和运行过程。 6. 参考Spring源码的测试用例,了解Spring框架的各个组件的使用方法和测试方法。 7. 参考Spring源码的设计模式和最佳实践,了解如何设计和实现高质量的Java应用程
从MessageSource源码出发实战spring·i18n国际化的三种改造方案 从源码去看MessageSource的几个实现类的源码出发,基于spring的国际化支持,实现国际化的开箱即用,静态文件配置刷新生效以及全局异常国际化处理。
重磅!程序员都在学的Spring实战(第6版),你竟然还没有掌握? 不知不觉已经年底了,可能很多程序员还在迷茫阶段,不知道该如何学习进步。 也因为疫情的缘故,都阳了!也可能因为被裁了,在家里面待着,除了刷剧就是看视频、玩游戏,也就都默默躺平了..... 殊不知,你该起来学习了,在躺平下去就真的废了,没有经济来源,没有工作,也就赶不上明年金三银四招聘旺季。 很不巧的是,《Spring实战第5版》新升级——第六版竟然重磅上市!这些总有的学了吧?
《Spring Cloud Alibaba 从入门到实战》电子版地址 《Spring Cloud Alibaba 从入门到实战》是 Spring Cloud Alibaba 训练营的总结,书籍涵盖从基础知识到具体技术的讲解,从要点到实践,让你也能从入门到实战。
Spring - FactoryBean扩展实战_MyBatis-Spring 启动过程源码解读 在理解 MyBatis-Spring 的启动过程时,需要重点把握的是 `SqlSessionTemplate` 核心类的设计理念及其实现过程,使用了JDK动态代理机制。
Spring事务传播行为实战 Spring框架提供了事务管理的标准实现,且可以通过注解或者XML文件的方式声明和配置事务。 通过异步事件的方式解耦服务调用,可以提高程序的响应速度,并且避免因为事务传播行为而导致的事务问题。 本文以一个电商平台包裹出库的业务为实际背景,通过异步事件与线程池的方式解耦嵌套事务,提高程序并发性能;为了便于问题的分析和方案的理解,同时还讲解了Spring的事务管理,并着重介绍了几种不同的事务传播行为。
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载