mybatis 动态数据源mongodb mybatis动态创建数据源

admin2024-06-06  14

通过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)公共数据源配置

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_表名,第1张

公共数据源配置

2)数据源1配置

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_数据源_02,第2张

数据源1配置

3)数据源2配置

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_SQL_03,第3张

数据源2配置

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_SQL_04,第4张

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

5)LazyConnectionDataSourceProxy配置

LazyConnectionDataSourceProxy配置

LazyConnectionDataSourceProxy代理了AbstractRoutingDataSource。

2、重写AbstractRoutingDataSource的determineCurrentLookupKey方法

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_数据源_05,第5张

重写determineCurrentLookupKey方法

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_表名_06,第6张

ShardingContextHolder类源码

3、Mybatis的配置

1)定义会话工厂

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_数据源_07,第7张

会话工厂配置

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

2)配置事务管理器

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_数据源_08,第8张

事务管理器配置

dataSource属性引用lazyDataSource。

3)Mapper接口包扫描配置

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_SQL_09,第9张

Mapper接口包扫描配置

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

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_数据源_10,第10张

MybatisSqlInterceptor类源码

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_SQL_11,第11张

ShardingDataSourceRouter类源码

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

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_表名_12,第12张

UserShardingDataSourceRule类的源码

UserShardingDataSourceRule类的配置

mybatis 动态数据源mongodb mybatis动态创建数据源,mybatis 动态数据源mongodb mybatis动态创建数据源_SQL_13,第13张

UserShardingDataSourceRule类配置

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!