基于Mybatis的分库实践

来源:互联网 发布:windows api 界面 编辑:程序博客网 时间:2024/06/03 23:44

转自:http://www.jianshu.com/p/13f4a3a9765a点击打开链接

转载请标明出处尊重作者

思路

通过Mybatis的Interceptor拦截执行的SQL语句,判断SQL语句操作的表是否需要进行分库,若需要分库,则根据SQL语句的参数值和分库算法进行分库,分库核心使用Spring的AbstractRoutingDataSource进行数据源的动态切换,同时使用Spring的LazyConnectionDataSourceProxy代理AbstractRoutingDataSource,延迟获取JDBC的Connection对象,否则Mybatis的Interceptor在拦截SQL时,AbstractRoutingDataSource的determineCurrentLookupKey方法已经确定了数据源,也就不能进行切换了。

Mybatis拦截器

Mybatis在执行SQL语句前会产生一个包含SQL语句的Statement对象,并且SQL语句在Statement对象生成之前产生,因此可在Statement生成前拦截到SQL语句。Mybatis的Statement对象是通过RoutingStatementHandler的prepare方法生成的,所以可以拦截StatementHandler的prepare方法获取SQL语句和参数值(RoutingStatementHandler是StatementHandler接口的实现类)。

使用技术

Spring + Mybatis + Mysql + Druid(JDBC连接池),2个Mysql数据库实例

实践步骤

1、数据源配置

1)公共数据源配置


公共数据源配置

2)数据源1配置


数据源1配置

3)数据源2配置


数据源2配置

4)具有路由功能的数据源配置


具有路由功能的数据源配置

5)LazyConnectionDataSourceProxy配置


LazyConnectionDataSourceProxy配置

LazyConnectionDataSourceProxy代理了AbstractRoutingDataSource。

2、重写AbstractRoutingDataSource的determineCurrentLookupKey方法

定义类ShardingRoutingDataSource,继承AbstractRoutingDataSource,重写determineCurrentLookupKey方法


重写determineCurrentLookupKey方法

ShardingContextHolder是通过线程局部变量保存数据源的key值


ShardingContextHolder类源码

3、Mybatis的配置

1)定义会话工厂


会话工厂配置

dataSource属性引用lazyDataSource,同时配置Mybatis的拦截器。

2)配置事务管理器


事务管理器配置

dataSource属性引用lazyDataSource。

3)Mapper接口包扫描配置


Mapper接口包扫描配置

4、通过Mybatis的Interceptor拦截SQL语句进行分库

定义一个类,实现Interceptor接口。在intercept方法中拦截执行的SQL语句和参数值,分库逻辑可根据业务需要进行定义。例子中使用表名进行判断。


MybatisSqlInterceptor类源码

ShardingDataSourceRouter类,实现数据源key值的动态切换功能。doRoute方法有2个参数,第一个参数是表名,第二个参数是SQL参数的值,可以根据定义不同的分库算法。


ShardingDataSourceRouter类源码

doRoute方法中获取所有配置的ShardingDataSourceRule类,ShardingDataSourceRule类是一个抽象类,包含一个表名的属性。doRoute根据表名匹配ShardingDataSourceRule的实现类,ShardingDataSourceRule实现类的doSharding计算数据源的索引值,包含两个参数,第一个是SQL语句的参数值,第二个是数据源的个数。


UserShardingDataSourceRule类的源码

UserShardingDataSourceRule类的配置


UserShardingDataSourceRule类配置

T_USER是需要进行分库的表名。

基于Mybatis的分库与基于Spring的分库是类似的,一个是基于Mybatis的拦截器插件,一个是基于Spring的AOP的拦截器。


原创粉丝点击