Spring Data的Repositories----自定义存储库实现

【Spring连载】使用Spring Data的Repositories----自定义存储库实现

  • 一、定制单个存储库
    • 1.1 配置
    • 1.2 歧义的解决
    • 1.3 手动装配
  • 二、自定义基础存储库

Spring Data提供了各种选项,可以用很少的编码来创建查询方法。但是,当这些选项不能满足你的需求时,你还可以为存储库方法提供自己的自定义实现。本节将介绍如何做到这一点。

一、定制单个存储库

要用自定义功能丰富存储库,你必须首先定义一个fragment接口和自定义功能的实现,如下所示:
自定义存储库功能的接口

interface CustomizedUserRepository {void someCustomMethod(User user);
}

自定义存储库功能的实现

class CustomizedUserRepositoryImpl implements CustomizedUserRepository {public void someCustomMethod(User user) {// Your custom implementation}
}

与fragment接口相对应的类名中最重要的部分是Impl后缀。
实现本身不依赖于Spring Data,可以是一个常规的Spring bean。因此,你可以使用标准的依赖注入行为来注入对其他bean(如JdbcTemplate)的引用,参与aspects,等等。
然后,你可以让你的存储库接口扩展fragment接口,如下所示:
对存储库接口的更改

interface UserRepository extends CrudRepository<User, Long>, CustomizedUserRepository {// Declare query methods here
}

使用你的存储库接口扩展fragment接口将CRUD和自定义功能结合起来,使其可用于客户端。
Spring Data存储库是通过使用组成存储库组合的fragments来实现的。Fragments是基础存储库、功能切面(如QueryDsl)和自定义接口及他们的实现。每次向存储库接口添加接口时,都会通过添加fragment来增强组合。基本存储库和存储库切面的实现由每个Spring Data模块提供。
以下示例展示了自定义接口及其实现:
Fragments及其实现

interface HumanRepository {void someHumanMethod(User user);
}class HumanRepositoryImpl implements HumanRepository {public void someHumanMethod(User user) {// Your custom implementation}
}interface ContactRepository {void someContactMethod(User user);User anotherContactMethod(User user);
}class ContactRepositoryImpl implements ContactRepository {public void someContactMethod(User user) {// Your custom implementation}public User anotherContactMethod(User user) {// Your custom implementation}
}

下面的示例展示了扩展CrudRepository的自定义存储库的接口:
对存储库接口的更改

interface UserRepository extends CrudRepository<User, Long>, HumanRepository, ContactRepository {// Declare query methods here
}

存储库可以由多个自定义实现组成,这些实现按照声明的顺序导入。自定义实现的优先级高于基本实现和存储库切面。这种排序使您可以覆盖基本存储库和切面方法,并在两个fragments提供相同的方法签名时解决歧义。存储库fragments不限于在单个存储库接口中使用。多个存储库可能使用一个fragment接口,允许你在不同的存储库中重用自定义。
以下示例展示了一个存储库fragment及其实现:
Fragments覆盖save(…)

interface CustomizedSave<T> {<S extends T> S save(S entity);
}class CustomizedSaveImpl<T> implements CustomizedSave<T> {public <S extends T> S save(S entity) {// Your custom implementation}
}

下面的示例展示了使用上述存储库片段的存储库:
自定义存储库接口

interface UserRepository extends CrudRepository<User, Long>, CustomizedSave<User> {
}interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<Person> {
}

1.1 配置

存储库基础结构试图通过扫描在其中找到存储库的包下面的类来自动检测自定义实现片段(fragments)。这些类需要遵循将后缀默认追加Impl的命名约定。
以下示例展示了一个使用默认后缀的存储库和一个为后缀设置自定义值的存储库:
例1:配置示例

<repositories base-package="com.acme.repository" /><repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" />
@EnableMongoRepositories(repositoryImplementationPostfix = "MyPostfix")
class Configuration {}

前面示例中的第一个配置试图查找一个名为“com.acme.repository.CustomizedUserRepositoryImpl”的类,以充当自定义存储库实现。第二个示例试图查找“com.acme.repository.CustomizedUserRepositoryMyPostfix”。

1.2 歧义的解决

如果在不同的包中找到多个具有匹配类名的实现,那么Spring Data将使用bean名称来确定要使用哪一个。
给定前面显示的CustomizedUserRepository的以下两个自定义实现,将使用第一个实现。它的bean名称是customizedUserRepositoryImpl,它与fragment接口(CustomizedUserRepository)加上后缀Impl的名称相匹配。
例2:解决(Resolution)不明确的实现

package com.acme.impl.one;class CustomizedUserRepositoryImpl implements CustomizedUserRepository {// Your custom implementation
}Copied!
package com.acme.impl.two;@Component("specialCustomImpl")
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {// Your custom implementation
}

如果你用@Component(“specialCustom”)注解UserRepository接口,那么bean名称加上Impl将与“com.acme.impl.two”中为存储库实现定义的名称相匹配,并使用它来代替第一个。

1.3 手动装配

如果你的自定义实现仅使用基于注解的配置和自动装配,那么前面展示的方法效果很好,因为它被当成任何其他Spring bean。如果你的实现fragment bean需要特殊的装配,那么你可以声明bean并根据上一节中描述的约定对其进行命名。然后,基础结构(infrastructure)通过名称引用手动定义的bean定义,而不是自己创建一个定义。以下示例展示了如何手动装配自定义实现:
例3:手动装配自定义实现

<repositories base-package="com.acme.repository" /><beans:bean id="userRepositoryImpl" class=""><!-- further configuration -->
</beans:bean>
class MyClass {MyClass(@Qualifier("userRepositoryImpl") UserRepository userRepository) {}
}

二、自定义基础存储库

当你想要自定义基本存储库行为以使所有存储库都受到影响时,上一节中描述的方法需要自定义每个存储库接口。要更改所有存储库的行为,可以创建一个扩展特定持久性技术存储库基类的实现。然后,该类充当存储库代理的自定义基类,如以下示例所示:
自定义存储库基类

class MyRepositoryImpl<T, ID>extends SimpleJpaRepository<T, ID> {private final EntityManager entityManager;MyRepositoryImpl(JpaEntityInformation entityInformation,EntityManager entityManager) {super(entityInformation, entityManager);// Keep the EntityManager around to used from the newly introduced methods.this.entityManager = entityManager;}@Transactionalpublic <S extends T> S save(S entity) {// implementation goes here}
}

该类需要有一个父类的构造函数,特定存储的存储库工厂实现使用该构造函数。如果存储库基类有多个构造函数,请重写采用EntityInformation加上特定于存储库的基础结构对象(如EntityManager或template类)的构造函数。
最后一步是让Spring Data基础结构了解定制的存储库基类。在配置中,你可以使用repositoryBaseClass来执行此操作,如以下示例所示:
例4:配置自定义存储库基类

<repositories base-package="com.acme.repository"base-class="….MyRepositoryImpl" />
@Configuration
@EnableMongoRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13年老鸟整理,性能测试技术知识体系总结,从零开始打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 从个人的实践经验…

多线程案例及常用模式

一.单例模式——经典的设计模式 什么是单例模式&#xff1a;就是规定一个类只能创建一个对象&#xff0c;也就是保证某个类在程序中只存在唯一一个实例&#xff0c;而不会创建出多个实例 根据对象创建的时机不同&#xff0c;可以分为饿汉模式和懒汉模式 1.饿汉模式 在类加载…

Cloudflare Tunnel:无惧DDOS_随时随地安全访问局域网Web应用

利用此方法&#xff0c;您可以在局域网&#xff08;尤其是NAS&#xff09;上搭建的Web应用支持公网访问&#xff0c;成本低而且操作简单&#xff01; 如果这是博客的话&#xff0c;它还可以有效防止DDOS攻击&#xff01; 准备工作&#xff1a; 需要一个域名&#xff08;推荐N…

类模板和函数模板

在 C 中&#xff0c;类模板和函数模板是用来创建通用类型的模板&#xff0c;允许在编写代码时将类型参数化。这种泛型编程方式可以帮助我们编写更通用、更灵活的代码&#xff0c;提高代码的重用性和可维护性。 类模板&#xff08;Class Templates&#xff09; 类模板允许在类定…

服务端请求伪造(SSRF)

漏洞概述 服务器会根据用户提交的 URL 发送一个 HTTP 请求。使用用户指定的 URL &#xff0c; Web 应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 如果没有对用户提交 URL 和远端服务器所返回的信息做合适的验证或过滤&#xff0c;就有可能存在 “ 请求伪造…

【微服务学习笔记(二)】Docker、RabbitMQ、SpringAMQP、Elasticseach

【微服务学习笔记&#xff08;二&#xff09;】Docker、RabbitMQ、SpringAMQP、Elasticseach Docker镜像和容器安装基础命令Dockerfile自定义镜像 MQ&#xff08;服务异步通讯&#xff09;RabbitMQ安装使用消息模型 SpringAMQP消息发送消息接收Work Queue 工作队列发布订阅Fano…

抖音小店精选联盟关闭了,是什么原因?怎么解决?

大家好&#xff0c;我是电商糖果 不知道大家有没有出现这样的情况&#xff0c;店铺后台的精选联盟莫名其妙的关闭了。 这里糖果就来给大家列举一下&#xff0c;出现联盟关闭的几种原因&#xff0c;以及怎么解决。 第一种&#xff1a;体验分低于70 这个是联盟关闭最常出现的情…

Python中的运算符介绍

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能…

使用Docker搭建Caddy

使用Docker搭建Caddy&#xff0c;可以快速部署一个轻量级的、支持自动HTTPS的web服务器。下面将分别介绍使用Docker CLI和Docker Compose两种方式来搭建Caddy服务器&#xff0c;并给出配置文件示例以及参数解释。 使用Docker CLI搭建Caddy 首先&#xff0c;确保你的系统上已安…

VR全景在智慧园区中的应用

VR全景如今以及广泛的应用于生产制造业、零售、展厅、房产等领域&#xff0c;如今720云VR全景更是在智慧园区的建设中&#xff0c;以其独特的优势&#xff0c;发挥着越来越重要的作用。VR全景作为打造智慧园区的重要角色和呈现方式已经受到了越来越多智慧园区企业的选择和应用。…

vue3 实现一个tab切换组件

一. 效果图 二. 代码 文件 WqTab.vue: <template><div ref"wqTabs" class"wq-tab"><template v-for"tab in tabs" :key"tab"><div class"tab-item" :class"{ ac: tabActive tab.key }" c…

网络地址转换协议NAT

网络地址转换协议NAT NAT的定义 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地IP地址&#xff08;即仅在本专用网内使用的专用地址&#xff09;&#xff0c;但现在又想和因…

浏览器缓存 四种缓存分类 两种缓存类型

浏览器缓存 本文主要包含以下内容&#xff1a; 什么是浏览器缓存按照缓存位置分类 Service WorkerMemory CacheDisk CachePush Cache 按照缓存类型分类 强制缓存协商缓存 缓存读取规则浏览器行为 什么是浏览器缓存 在正式开始讲解浏览器缓存之前&#xff0c;我们先来回顾一…

Python 的练手项目有哪些值得推荐?

Python 是一种强大的编程语言&#xff0c;有许多值得推荐的练手项目。以下是一些例子&#xff1a; 数据分析&#xff1a;利用 Python 的数据分析库&#xff08;如 pandas 和 NumPy&#xff09;处理和分析数据。你可以尝试对数据进行清洗、可视化&#xff0c;或者构建简单的预测…

韶音运动耳机好用吗?南卡、墨觉、韶音骨传导耳机三款全面评测

音乐是我生活中不可或缺的调味品&#xff0c;它伴随着我度过了无数个清晨的慢跑以及夜晚的悠闲散步。但是传统入耳式耳机总是让我感到不适&#xff0c;虽然它有着不错的降噪能力&#xff0c;但是很容易忽视周围环境的安全&#xff0c;而且运动的时候老容易掉。然后我遇到了骨传…

C++ 错误: 不能将“System::Object^“类型的值分配到“double“类型的实体

错误信息&#xff1a; 错误: 不能将"System::Object^"类型的值分配到"double"类型的实体 解决方案&#xff1a; 这个错误在C/CLI编程环境下出现&#xff0c;是因为你正在尝试将.NET类型System::Object^&#xff08;托管对象指针&#xff09;直接赋值给一…

个人博客网站前端页面的实现

博客网站前端页面的实现 博客登录页 相关代码 login.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

8U VPX通用系统平台

19” 上架机箱&#xff0c;8U高 ? 外形尺寸532.6mm x 482.6mm x 387.2mm (HxWxD)&#xff0c; ? 前部支持12个标准6U5HP板卡插槽&#xff0c;2个6U10HP VPX电源插槽 ? 支持12个标准6U5HP RTM卡插槽 ? 底部可拆卸风扇盘&#xff0c;散热风道由下至上 ?…

基于SpringBoot和PotsGIS的各省地震震发可视化分析

目录 前言 一、后台接口研发 1、控制层实现 2、Mapper访问层 3、空间查询分析 二、前端可视化展示 1、主体地图定义 2、行政区划列表定义 3、行政区划定位 三、数据分析 1、北京市 2、广东省 3、青海省 4、湖南省 总结 前言 在之前的博文中&#xff0c;我们…

如何在Linux使用Docker部署Firefox并实现无公网IP访问本地浏览器

文章目录 1. 部署Firefox2. 本地访问Firefox3. Linux安装Cpolar4. 配置Firefox公网地址5. 远程访问Firefox6. 固定Firefox公网地址7. 固定地址访问Firefox Firefox是一款免费开源的网页浏览器&#xff0c;由Mozilla基金会开发和维护。它是第一个成功挑战微软Internet Explorer浏…