摘要:最近公司项目需要支持,每个数据库地址不同,需求就是修改配置文件,添加或者删除数据库配置,重启系统后就可以完成,不需要额外修改代码。那怎么来完成数据库的访问的呢核心类是,而变量才是完成访问的关键,而这个其实就是。
最近公司项目需要支持multi-tenancy,每个tenant数据库地址不同,需求就是修改配置文件,添加或者删除数据库配置,重启系统后就可以完成,不需要额外修改代码。
网上搜索了一下,基本上都是将配置写在了代码里了,例如:http://www.devzxd.top/2017/06...,不能动态增减数据库配置,并且对不同的数据库创建不同的Repository。继续Google之后,在github上找到一个例子multi-tenant-spring-mongodb,看了一下代码,还是不符合需求。没办法,只能看代码,调试来看看自己能不能实现这个需求了。
那spring-data-mongodb怎么来完成数据库的访问的呢?核心类是SimpleMongoRepository,而mongoOperations变量才是完成访问的关键,而这个mongoOperations其实就是mongoTemplate。那就意味着如果我们能够动态改变这个mongoTemplate的值就可以切换数据库了,窃喜。
解决的方法有了,但是如何实现呢?库并没有提供类似Hibernate那样的MultiTenantConnectionProvider和CurrentTenantIdentifierResolver来帮助我们实现。既然spring是通过AOP和Proxy来完成功能的调用的,我们似乎也可以这么玩。
我们要对所有的Repository方法的访问创建一个PointCut,这样我们就可以在访问之前搞事情了。
利用反射拿到joinPoint的target,然后调用用AopProxyUtils.getSingletonTarget(target)取到最终的SimpleMongoRepository实例。
通过反射设置mongoOperations的值。
代码如下:
@Repository public interface WidgetDataRepository extends MongoRepository{ }
// 注意:线程不安全!!! @Around("execution(* com.example.demo.dao.mongo.MongoWidgetDataRepo.*(..))") public Object doSwitch(ProceedingJoinPoint joinPoint) throws Throwable { // 拿到我们需要的tenant String tenant = (String) RequestContextHolder.currentRequestAttributes().getAttribute("tenant", SCOPE_REQUEST); tenant = tenant == null ? "test" : tenant; // 通过反射获取到target Field methodInvocationField = joinPoint.getClass().getDeclaredField("methodInvocation"); methodInvocationField.setAccessible(true); ReflectiveMethodInvocation o = (ReflectiveMethodInvocation) methodInvocationField.get(joinPoint); Field targetField = o.getClass().getDeclaredField("target"); targetField.setAccessible(true); Object target = targetField.get(o); // 获得SimpleMongoRepository,并往里面填入值 Object singletonTarget = AopProxyUtils.getSingletonTarget(target); Field mongoOperationsField = singletonTarget.getClass().getDeclaredField("mongoOperations"); mongoOperationsField.setAccessible(true); mongoOperationsField.set(singletonTarget, ac.getBean("mongoTemplate" + tenant)); return joinPoint.proceed(); }
这样我们就可以完成数据库的切换了,可以利用spring-data-mongodb,尽可能的少些模板代码。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/19174.html
摘要:最近公司项目需要支持,每个数据库地址不同,需求就是修改配置文件,添加或者删除数据库配置,重启系统后就可以完成,不需要额外修改代码。那怎么来完成数据库的访问的呢核心类是,而变量才是完成访问的关键,而这个其实就是。 最近公司项目需要支持multi-tenancy,每个tenant数据库地址不同,需求就是修改配置文件,添加或者删除数据库配置,重启系统后就可以完成,不需要额外修改代码。 网上搜...
摘要:踩到许多坑,记录下一些基于的东西吧首先。先创建个集合,保存写信息,然后再创建集合,可以发现存储的时候变成了一个引用类型。王大锤那么查询的时候,如果要根据查询班级怎么办,的查询也非常简单。详情可以查看官方文档用法 刚接触mongodb不久。踩到许多坑,记录下一些基于spring-data-mongodb的东西吧 首先。应该了解下什么情况下使用mongodb,什么情况下用mysql: 业...
摘要:踩到许多坑,记录下一些基于的东西吧首先。王大锤那么查询的时候,如果要根据查询班级怎么办,的查询也非常简单。详情可以查看官方文档用法 刚接触mongodb不久。踩到许多坑,记录下一些基于spring-data-mongodb的东西吧 首先。应该了解下什么情况下使用mongodb,什么情况下用mysql: 业务需要事物,使用mysql,因为mongodb不支持事物 数据量大,但是数据本身...
摘要:踩到许多坑,记录下一些基于的东西吧首先。王大锤那么查询的时候,如果要根据查询班级怎么办,的查询也非常简单。详情可以查看官方文档用法 刚接触mongodb不久。踩到许多坑,记录下一些基于spring-data-mongodb的东西吧 首先。应该了解下什么情况下使用mongodb,什么情况下用mysql: 业务需要事物,使用mysql,因为mongodb不支持事物 数据量大,但是数据本身...
摘要:版本不支持支持为,如果使用并且使用,则会出现提示,编译出错。扫描的仓库目录,会自动扫描扩展了接口的接口进行注入。 mongodb介绍 MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。 MongoD...
阅读 1334·2021-11-15 11:45
阅读 3107·2021-09-27 13:36
阅读 2823·2019-08-30 15:54
阅读 967·2019-08-29 12:38
阅读 2880·2019-08-29 11:22
阅读 2969·2019-08-26 13:52
阅读 2000·2019-08-26 13:30
阅读 537·2019-08-26 10:37