在项目中使用到了若依,想从头实现一下。思路就是把项目中涉及到的知识内容单独拎出来理解和做测试,然后再合到系统里去,重点的地方会将涉及到的知识进行总结和扩展。顺序是由后端到前端。 代码地址: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,如果说
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.可以通过前台界面配置指定数据源
参考实现:
http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90
https://github.com/lenve/tienchin-video
标签:一步,--,数据源,ThreadLocal,线程,DataSource,注解,dataSource From: https://www.cnblogs.com/hunji-fight/p/17030427.html