一步一步实现若依框架--2.1实现多数据源
2023-04-18 15:21:05 时间
在项目中使用到了若依,想从头实现一下。思路就是把项目中涉及到的知识内容单独拎出来理解和做测试,然后再合到系统里去,重点的地方会将涉及到的知识进行总结和扩展。顺序是由后端到前端。 代码地址:https://github.com/hunji/RYMirror
common模块中的功能,大部分是通过自定义注解+AOP来实现通用功能。第2章节就会逐个实现各注解功能。本篇2.1是实现多数据源。代码中有打tag,跟着步骤来的,可以边看程序边看总结。
1)原理:
mybatis在执行sql前通过数据源去找数据库连接-->determineCurrentLookupKey(AbstractRoutingDataSource);所以通过注解拦截方法,在调用之前动态切换数据源名称即可。切换数据源,就要先给spring注入这些定义好的数据源,也就是程序中自定义的类DynamicDataSource的实例。所以问题就转换成了怎么准备多个数据源。通过DruidConfig中注入数据源,其中共性的属性由DruidProperties设置,各个数据源的特有属性根据注解ConfigurationProperties设置。最后,由于不同的请求是在不同的线程中的,可能去请求不同的数据源,所以这里要使用ThreadLocal保证现场安全来切换数据源名称。
2)ThreadLocal它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)
ThreadLocal 的特点:
-
ThreadLocal可以为当前线程关联一个数据。(它可以像Map一样存取数据,key为当前线程)
-
每一个 ThreadLocal对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个ThreadLocal对象实例。
-
每个ThreadLocal对象实例定义的时候,一般都是static类型
-
ThreadLocal中保存数据,在线程销毁后。会由JVM虚拟自动释放。这里销毁的是threadmap,如果说
这里有可能造成内存溢出,所以切点执行后手动清除一下。
3)@annotation 方法级别@within 对象级别
4)查找注解的方式:
public DataSource getDataSource(ProceedingJoinPoint point) { MethodSignature signature = (MethodSignature) point.getSignature(); // 查找方法上的注解 DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); if (Objects.nonNull(dataSource)) { return dataSource; } // 查找类上的注解 return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); }
这个方法就是为什么DataSource注解优先级是先方法后类
5)关于ConfigurationProperties的使用
有个问题就是各个数据源的name,password,url怎么设置到动态数据源中的。这里其实是ConfigurationProperties的用法。@Configuration注解的配置类中通过@Bean注解在某个方法上将方法返回的对象定义为一个Bean,并使用配置文件中相应的属性初始化该Bean的属性。
@Bean @ConfigurationProperties("spring.datasource.druid.slave") @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") public DataSource slaveDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); return druidProperties.dataSource(dataSource); } public DruidDataSource dataSource(DruidDataSource datasource)
返回类型DruidDataSource是有这些属性的。
这种方式提供了一个思路,就是解决怎么把既有共性,又有特殊属性的一些配置,读取到同一个类中。可以使用一个map来获取这些属性去处理,也可以像上面这种方式,需用自己去map中遍历,
6) system模块里的mybatis是从哪里引入依赖的?system 依赖 common,conmon中引入了pagehelper,pagehelper中依赖了mybatis
7)mybatis开启驼峰命名自动映射 mapUnderscoreToCamelCase
8)单元测试
复制一个数据库,重命名为ry-vue2,修改sysUser中的数据。在system模块中添加sysUser的相关代码,在admin的test中添加单元测试。
@Service public class SysUserServiceImpl implements ISysUserService { @Autowired private SysUserMapper mapper; @Override @DataSource(DataSourceType.MASTER) public List<SysUser> getAllUsersMaster() { return mapper.getAllUsersMaster(); } @Override @DataSource(DataSourceType.SLAVE) public List<SysUser> getAllUsersSlave() { return mapper.getAllUsersSlave(); } }
==》扩展点(可以扩展的内容):
1.多数据源在yml文件中加上后不需要改程序
2.可以通过前台界面配置指定数据源
代码地址:
https://github.com/hunji/RYMirror/releases/tag/2.1%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击