思路
通過Mybatis的Interceptor攔截執(zhí)行的SQL語句漂佩,判斷SQL語句操作的表是否需要進(jìn)行分庫(kù)奕扣,若需要分庫(kù)卿操,則根據(jù)SQL語句的參數(shù)值和分庫(kù)算法進(jìn)行分庫(kù)扳肛,分庫(kù)核心使用Spring的AbstractRoutingDataSource進(jìn)行數(shù)據(jù)源的動(dòng)態(tài)切換叔汁,同時(shí)使用Spring的LazyConnectionDataSourceProxy代理AbstractRoutingDataSource统求,延遲獲取JDBC的Connection對(duì)象检碗,否則Mybatis的Interceptor在攔截SQL時(shí),AbstractRoutingDataSource的determineCurrentLookupKey方法已經(jīng)確定了數(shù)據(jù)源球订,也就不能進(jìn)行切換了后裸。
Mybatis攔截器
Mybatis在執(zhí)行SQL語句前會(huì)產(chǎn)生一個(gè)包含SQL語句的Statement對(duì)象,并且SQL語句在Statement對(duì)象生成之前產(chǎn)生冒滩,因此可在Statement生成前攔截到SQL語句微驶。Mybatis的Statement對(duì)象是通過RoutingStatementHandler的prepare方法生成的,所以可以攔截StatementHandler的prepare方法獲取SQL語句和參數(shù)值(RoutingStatementHandler是StatementHandler接口的實(shí)現(xiàn)類)开睡。
使用技術(shù)
Spring + Mybatis + Mysql + Druid(JDBC連接池)因苹,2個(gè)Mysql數(shù)據(jù)庫(kù)實(shí)例
實(shí)踐步驟
1、數(shù)據(jù)源配置
1)公共數(shù)據(jù)源配置
2)數(shù)據(jù)源1配置
3)數(shù)據(jù)源2配置
4)具有路由功能的數(shù)據(jù)源配置
5)LazyConnectionDataSourceProxy配置
LazyConnectionDataSourceProxy代理了AbstractRoutingDataSource篇恒。
2扶檐、重寫AbstractRoutingDataSource的determineCurrentLookupKey方法
定義類ShardingRoutingDataSource,繼承AbstractRoutingDataSource胁艰,重寫determineCurrentLookupKey方法
ShardingContextHolder是通過線程局部變量保存數(shù)據(jù)源的key值
3款筑、Mybatis的配置
1)定義會(huì)話工廠
dataSource屬性引用lazyDataSource,同時(shí)配置Mybatis的攔截器腾么。
2)配置事務(wù)管理器
dataSource屬性引用lazyDataSource奈梳。
3)Mapper接口包掃描配置
4、通過Mybatis的Interceptor攔截SQL語句進(jìn)行分庫(kù)
定義一個(gè)類解虱,實(shí)現(xiàn)Interceptor接口攘须。在intercept方法中攔截執(zhí)行的SQL語句和參數(shù)值,分庫(kù)邏輯可根據(jù)業(yè)務(wù)需要進(jìn)行定義殴泰。例子中使用表名進(jìn)行判斷于宙。
ShardingDataSourceRouter類,實(shí)現(xiàn)數(shù)據(jù)源key值的動(dòng)態(tài)切換功能悍汛。doRoute方法有2個(gè)參數(shù)捞魁,第一個(gè)參數(shù)是表名,第二個(gè)參數(shù)是SQL參數(shù)的值离咐,可以根據(jù)定義不同的分庫(kù)算法署驻。
doRoute方法中獲取所有配置的ShardingDataSourceRule類,ShardingDataSourceRule類是一個(gè)抽象類健霹,包含一個(gè)表名的屬性旺上。doRoute根據(jù)表名匹配ShardingDataSourceRule的實(shí)現(xiàn)類,ShardingDataSourceRule實(shí)現(xiàn)類的doSharding計(jì)算數(shù)據(jù)源的索引值糖埋,包含兩個(gè)參數(shù)宣吱,第一個(gè)是SQL語句的參數(shù)值,第二個(gè)是數(shù)據(jù)源的個(gè)數(shù)瞳别。
UserShardingDataSourceRule類的配置
T_USER是需要進(jìn)行分庫(kù)的表名征候。
基于Mybatis的分庫(kù)與基于Spring的分庫(kù)是類似的杭攻,一個(gè)是基于Mybatis的攔截器插件,一個(gè)是基于Spring的AOP的攔截器疤坝。