Spring Data JPA 从入门到精通~自定义实现Repository

EntityManager 的获取方式

我们既然要自定义,首先讲一下 EntityManager 的两种获取方式。

1. 通过 @PersistenceContext 注解。

通过将 @PersistenceContext 注解标注在 EntityManager 类型的字段上,这样得到的 EntityManager 就是容器管理的 EntityManager。由于是容器管理的,所以我们不需要也不应该显式关闭注入的 EntityManager 实例。

@Repository
@Transactional(readOnly = true)
public class UserRepositoryImpl implements UserRepositoryCustom {@PersistenceContext  //获得entityManager的实例EntityManager entityManager;
}

2. 继承 SimpleJpaRepository 成为子类,实现构造方法即可,这时候我们直接用父类里面的 EntityManager 即可。

public class BaseRepositoryCustom<T, ID> extends SimpleJpaRepository<T, ID> {public BaseRepositoryCustom(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {super(entityInformation, entityManager);}public BaseRepositoryCustom(Class<T> domainClass, EntityManager em) {super(domainClass, em);}
}

自定义 Repository 的两种场景

我们自定义实现 Repository,主要的应用场景有两种:

  • 个别特殊化场景,私有的。
  • 公用的通用的场景,替代默认的 SimpleJpaRepository 的场景,架构层面出发。

1. 自定义个别的特殊场景,私有的 Repository。

这种方法就是需要自己创建一个接口,和对应的接口实现类,若需要用到特殊化的实现方法的话,***Respository 只需要继承你自定义的接口即可,主要有两种能力:

  • 实现自定义接口
  • 可以直接覆盖 Spring Data JPA 给我们提供的默认 ***Respository 的接口里面的方法。

案例1:单个私有的 Repository 接口实现类

(1)创建自定义接口

/*** @author jack*/
public interface UserRepositoryCustom {/*** 自定义一个查询方法,name的like查询,此处仅仅是演示例子,实际中直接用QueryMethod即可* @param firstName* @return*/List<User> customerMethodNamesLike(String firstName);
}

(2)自定义存储库功能的实现

/*** 用@Repository 将此实现交个Spring bean加载* 咱们模仿SimpleJpaRepository 默认将所有方法都开启一个事务*/
@Repository
@Transactional(readOnly = true)
public class UserRepositoryCustomImpl implements UserRepositoryCustom {@PersistenceContextEntityManager entityManager;/*** 自定义一个查询firstname的方法* @param firstName* @return*/@Overridepublic List<User> customerMethodNamesLike(String firstName) {Query query = entityManager.createNativeQuery("SELECT u.* FROM user as u " +"WHERE u.name LIKE ?", User.class);query.setParameter(1, firstName + "%");return query.getResultList();}
}

我们这里采用 entityManager,当然了也不排除自己通过最底层的 JdbcTemplate 来自己实现逻辑。

(3)由于这个接口是为 User 单独写的,但是同时也可以继承和 @Repository 的任何子类。

/*** 使用的时候直接继承 UserRepositoryCustom接口即可*/
public interface UserRepository extends Repository<User, Long>,UserRepositoryCustom {
}

Controller 的调用方式如下:

/*** 调用我们自定义的实现方法** @return*/
@GetMapping(path = "/customer")
@ResponseBody
public Iterable<User> findCustomerMethodNamesLike() {return userRepository.customerMethodNamesLike("jack");
}

(4)其实通过上述方法我们可以实现多个自定义接口:

//如:我们自定义了HumanCustomerRepository, ContactCustomerRepository两个Repository
interface UserRepository extends CrudRepository<User, Long>, HumanCustomerRepository, ContactCustomerRepository {// 用的时候只需要继承多个自定义接口即可
}

(5)覆盖 JPA 里面的默认实现方法

Spring Data JPA 的底层实现里面,自定义的 Repositories 的实现类和方法要高于它帮我们提供的 Repositories,所以当我们有场景需要覆盖默认实现的时候其 demo 如下:

//假设我们要覆盖默认的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> {
}
//CustomizedSave通过泛化可以被多个Repository使用
interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<Person> {
}

实际工作中应用于逻辑删除场景:

在实际工作的生产环境中,我们可能经常会用到逻辑删除,所以做法是一般自定义覆盖 Data JPA 帮我们提供 remove 方法,然后实现逻辑删除的逻辑即可。

2:公用的通用的场景,替代默认的 SimpleJpaRepository 的场景,从架构层面出发。

案例2:定义一个公用的 Repository 接口的实现类。

通过构造方法获得 EntityManager,需要用到 Java 的泛化技术。当你想将一个方法添加到所有的存储库接口时,上述方法是不可行的,要将自定义行为添加到所有存储库,首先添加一个中间接口来声明共享行为。

(1)声明定制共享行为的接口,用 @NoRepositoryBean:

//因为要公用,所以必须要通用,不能失去本身的Spring Data JPA给我们提供的默认方法,所有我们继承相关的Repository类
@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {void sharedCustomMethod(ID id);
}

(2)继承 SimpleJpaRepository 扩展自己的方法实现逻辑:

public class MyRepositoryImpl<T, ID extends Serializable>extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> {private final EntityManager entityManager;public MyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {super(entityInformation, entityManager);// Keep the EntityManager around to used from the newly introduced methods.this.entityManager = entityManager;}public void sharedCustomMethod(ID id) {// 通过entityManager实现自己的额外方法的实现逻辑。这里不多说了}
}

注意:该类需要具有专门的存储库工厂实现使用超级类的构造函数,如果存储库基类有多个构造函数,则覆盖一个 EntityInformation 加上特定于存储的基础架构对象(例如,一个 EntityManager 或一个模板类),也可以重写 SimpleJpaRepository 的任何逻辑。如逻辑删除放在这里面实现,就不要所有的 Repository 去关心实现哪个接口了。

(3)使用 JavaConfig 配置自定义 MyRepositoryImpl 作为其他接口的动态代理的实现基类。

具有全局的性质,即使没有继承它所有的动态代理类也会变成它。

@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }

(4)使用的时候就可以显示的选择用哪个接口,从而选择性的暴露 SimpleJpaRepository 的实现方法。

现在,各个存储库接口将扩展此中间接口,而不是扩展 Repository 接口以包含声明的功能。接下来,创建扩展了持久性技术特定的存储库基类的中间接口的实现。然后,该类将用作存储库代理的自定义基类。

//如果你要使用你自定义的全局MyRepositoryImpl只需要继承接口即可,如下:
interface PersonRepository extends MyRepositoryImpl<Person, Long>{
}

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

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

相关文章

一图看懂阿里云IoT战略

来源&#xff1a;云栖社区从万物互联到万物智联&#xff0c;离不开“无处不在的计算”。阿里云IoT在云边端部署了可协同的计算&#xff0c;基于物联网使能平台联合开发者、芯片模组厂商、行业合作伙伴等在城市、生活、汽车、制造四大领域已完成深度布局&#xff0c;即一朵云、两…

matlab机器人模型仿真,一知半解|MATLAB机器人建模与仿真控制(1)

各位机器人技术爱好者们&#xff0c;大家好&#xff01;很荣幸受古月老师邀请&#xff0c;成为古月居的签约作者。希望在这里可以同大家相互交流与学习。始终觉得自己能力不足&#xff0c;但终于还是硬着头皮开始了在古月居的第一篇博客。由于我是机械专业出身&#xff0c;在接…

第四期《Summer Tree》 已经整理完毕

虽然已经整理完毕&#xff0c;但是却没有空间上传&#xff0c;由于太大了上传不了.下次再补充回来 如果地址下载不到&#xff0c;告诉我。呵呵 我上传在微软共享空间里面 在这里可以下载在这里转载于:https://www.cnblogs.com/hero82748274/archive/2009/06/06/1497771.html

研究报告:城市大脑的起源、现状与未来趋势

报告撰写人&#xff1a;刘锋 《互联网进化论》作者&#xff0c;计算机博士2009年1月&#xff0c;IBM公司首席执行官彭明盛首次提出“智慧地球”&#xff0c;建议政府投资新一代的智慧型基础设施。此后智慧城市建设在世界范围内展开&#xff0c;在中国有上百个地区提出建设“智慧…

Spring Data JPA 从入门到精通~实际工作的应用场景

在实际工作中&#xff0c;有哪些场景会用到自定义 Repository 呢&#xff0c;这里列出几种实际在工作中的应用案例。 1. 逻辑删除场景 可以用到上面说的两种实现方式&#xff0c;如果有框架级别的全局自定义 Respository 那就在全局实现里面覆盖默认 remove 方法&#xff0c;…

Linux IO - 同步,异步,阻塞,非阻塞

From&#xff1a;http://blog.csdn.net/historyasamirror/article/details/5778378 同步/异步&#xff0c;阻塞/非阻塞概念深度解析&#xff1a;http://blog.csdn.net/lengxiao1993/article/details/78154467 知乎上关于 阻塞和非阻塞、同步和异步 之间区别的生动解释。 htt…

java treeset比较,java中TreeSet的两种排序比较的方式

第一种是使得元素具有比较性第二种是让集合具有比较性具体代码步骤如下&#xff1a;import java.util.*;/** TreeSet&#xff1a;可以自动对对集合中的元素进行排序* 第一种比较方式* 步骤&#xff1a;* 1.让元素对象的类具有比较性&#xff0c;并实现Comparable接口* 2.对其中…

在 IE 中使用 HTML5 元素

一个HTML5范本 <html><head><style>blah {color:red;}</style></head><body><blah>Hello!</blah></body></html>一个简洁的 方法 让样式在 IE 中作用到未知的元素上——仅需 JS 创建此未知元素即可&#xff1a; &…

微软 AI 设计原则:成为弱者,再带来惊喜

来源&#xff1a;36Kr 作者&#xff1a;木木子编者按&#xff1a;AI设计的思路是什么&#xff1f;更完美&#xff1f;更能想用户之所想&#xff1f;本文作者Cliff Kuang在“The company studied personal assistants–human ones–to understand how to make a great machine…

vim 中的杀手级插件: vundle (vim 插件管理器)

From&#xff1a;http://zuyunfei.com/2013/04/12/killer-plugin-of-vim-vundle/ vundle.txt&#xff1a;https://github.com/VundleVim/Vundle.vim/blob/master/doc/vundle.txt Vundle 的具体介绍和配置&#xff1a;github repo&#xff1a;https://github.com/gmarik/vundl…

同步锁 php,python线程中同步锁详解

这篇文章主要为大家详细介绍了python线程中同步锁的相关资料&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下在使用多线程的应用下&#xff0c;如何保证线程安全&#xff0c;以及线程之间的同步&#xff0c;或者访问共享变量等问题是十分棘手的问题&a…

移动平均线分析法

移动平均线分析法是由道琼斯股价理论演变出来的一种股价趋势分析方法。其基本思想是消除股价随机波动的影响&#xff0c;以寻求股价波动的趋势。主要特点&#xff1a;1、追踪趋势&#xff1a;MA能够表示股价波动的趋势&#xff0c;并追踪这个趋势不轻易改变。2、滞后性&#xf…

Spring Data JPA 从入门到精通~Auditing及其事件详解

Auditing 及其事件详解 Auditing 翻译过来是审计和审核&#xff0c;Spring 的优秀之处在于帮我们想到了很多繁琐事情的解决方案&#xff0c;我们在实际的业务系统中&#xff0c;针对一张表的操作大部分是需要记录谁什么时间创建的&#xff0c;谁什么时间修改的&#xff0c;并且…

未来城市的无人机送货系统是怎样的?

来源&#xff1a; 资本实验室 作者&#xff1a;李鑫Siri通过移动应用下了一盒巴克拉拉面膜的订单&#xff0c;电商平台收到信息&#xff0c;发指令给最近的送货驳船。驳船上的无人机获取货物包裹后直接飞向Siri家。在不到8分钟的飞行后&#xff0c;无人机来到位于12层的Siri家…

Vim自动补全神器:YouCompleteMe

From&#xff1a;http://www.jianshu.com/p/d908ce81017a github 地址&#xff1a;https://github.com/Valloric/YouCompleteMe YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for Vim. 参考&#xff1a; https://github.com/Valloric/YouCom…

故障树分析法MATLAB,故障树分析(FTA)方法及其基于VC的软件设计的研究

故障树分析法(FTA)是一种评价复杂系统可靠性与安全性的重要方法。经过近四十年的发展,FTA技术已经有相对成熟的理论,但是在FTA的组合爆炸困难(计算量随故障树规模指数增长)、相关底事件的FTA 等方面还有待于进一步的研究。而且随着系统复杂性的加大,系统所含部件愈来愈多,研究系…

Windows 7硬盘安装方法大全

Windows 7硬盘安装方法大全&#xff0c;共整理出四种方法该Windows 7硬盘安装方法大全介绍了Windows 7下安装高版本的Windows 7&#xff0c;Vista下硬盘安装Windows 7&#xff0c;xp下硬盘安装Windows7等方法&#xff01; 一、 windows 7 系统下全新安装高版Windows7&#xff1…

对比 | 欧洲、美国、中国智慧城市的不同实践路径

来源&#xff1a;《上海城市规划》2018年第1期《欧美智慧城市最新实践与参考》作者&#xff1a;刘杨 龚烁 刘晋媛随着ICT、大数据、物联网等各类新兴技术的不断发展&#xff0c;智慧城市的运营和实践也不断趋于成熟。通过整理欧美各大典型智慧城市的最新实践案例&#xff0c;总…

C++ 使用 TinyXml 解析 XML 文件

知乎 C解析xml有什么好用的轮子? &#xff1a;https://www.zhihu.com/question/32046606 TinyXML-2 的 github地址和帮助文档&#xff1a;https://github.com/leethomason/tinyxml2 tinyxml 下载地址&#xff1a;https://sourceforge.net/projects/tinyxml/ *Please Note*…

java1.8.0,jdk1.8.0版本

【实例简介】jdk1.8版本&#xff0c;亲测可用。望有需求人士放心使用&#xff0c;下载。【实例截图】【核心代码】31449426-2a86-4e86-9718-9b4327dbb178└── jdk-8u161-windows-x64├── 1041│ ├── [5]DigitalSignature│ ├── [5]MsiDigitalSignatureEx│ ├─…