自定义路由组件实现分库分表

自定义路由组件实现分库分表学习总结(个人感悟)

DataSourceAutoConfig

初始化读取配置文件、加载配置文件数据至内存中并将值保存到bean容器(@Bean)

通过重写setEnvironment方法在容器启动时读取资源文件,并将库数量、表数量、分库分表数据源、默认数据源保存到对象和内存中。

DBRouterJoinPoint

SpringAOP:使用自定义注解@DBRouter作为切入点,属性key作为分库分表字段,在方法上使用@DBRouter注解时,会进入切面执行织入逻辑:根据传入的key(属性名)和方法入参(对象)得到key字段对应的值value,接着执行路由策略,计算value对应的分库分表的库编号和表编号,索引计算方式:

//库索引计算方式
int dbIdx = idx / dbRouterConfig.getTbCount() + 1;
//表索引计算方式
int tbIdx = idx - dbRouterConfig.getTbCount() * (dbIdx - 1);

将计算得到的库索引和表索引保存到ThreadLocal中,在后面的拦截SQL语句中会用到。记得在finally块中清除ThreadLocal,避免内存泄露

DBRouterStrategy

分表策略注解,标记SQL是否需要分表,内置属性splitTable为boolean,作用在类上,splitTable=true则表明该类下所有SQL都需要分表操作

DynamicMybatisPlugin

获得操作数据的表索引和库索引后,下一步就是执行SQL语句。此时SQL语句中的表名还是默认xml文件的表名,所以需要对SQL语句进行替换,该类通过继承Interceptor接口实现对所有SQL语句的拦截,也就是每次SQL语句执行前都会执行intercept方法。在该方法中,分两种情况:1.需要做拦截处理进行分表的SQL  2.不需要做分表的SQL。在这里是通过获取@DBRouterStrategy注解,判断该SQL是否需要分表,如果需要则通过正则表达式替换对应表名

DynamicDataSource

这个类的作用是动态数据源获取,每当切换数据源,都要从这个里面获取,刚开始看的时候,看到这个类继承了AbstractRoutingDataSource并重写了determineCurrentLookupKey方法,看到返回的是结果是计算库索引时保存到ThreadLocal中的库名,但是不理解为什么重写determineCurrentLookupKey方法就可以做到数据源的切换做到连接指定的库,看到AbstractRoutingDataSource的源码中getConnection连接数据库的方法中,调用了determineTargetDataSource方法,在该方法里会调用determineCurrentLookupKey方法得到一个Object对象,在这里就是我们返回的指定的库名,接着源码中根据库名获取数据源,这里用的是一个Map,key是Object类型,value是对应的数据源,其实就和在DataSourceAutoConfig类的dataSource方法中的targetDataSources一样,key是库名,value对应该库对应的数据源信息,看到这里我就明白了,通过继承AbstractRoutingDataSource类并重写determineCurrentLookupKey方法就可以做到动态切换数据源

你可能感兴趣的:(mybatis,java,mysql)