首页 > 其他分享 >一步一步实现若依框架--2.1实现多数据源

一步一步实现若依框架--2.1实现多数据源

时间:2023-01-06 14:44:41浏览次数:55  
标签:一步 -- 数据源 ThreadLocal 线程 DataSource 注解 dataSource

  在项目中使用到了若依,想从头实现一下。思路就是把项目中涉及到的知识内容单独拎出来理解和做测试,然后再合到系统里去,重点的地方会将涉及到的知识进行总结和扩展。顺序是由后端到前端。 代码地址: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.可以通过前台界面配置指定数据源

 

 

参考实现:

http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90

https://mp.weixin.qq.com/s?__biz=Mzg5OTgxOTg0Ng==&mid=2247483925&idx=1&sn=cd759057f3941f8e9bdb7d1a0c7599b4&chksm=c04c323cf73bbb2ac8c2e3278c92b4510545217ed5d13aa740590216124e3d0eae2b32b9bc91&scene=178&cur_album_id=2441331662295973890#rd

https://github.com/lenve/tienchin-video

 

标签:一步,--,数据源,ThreadLocal,线程,DataSource,注解,dataSource
From: https://www.cnblogs.com/hunji-fight/p/17030427.html

相关文章