如何用Mybatis分库分表
分庫
在分庫的時(shí)候 有時(shí)候?yàn)榱朔奖?一些表需要存放所有庫的信息,稱為全局庫。如:用戶表存放所有的用戶。
此時(shí)分庫的思路 數(shù)據(jù)庫分為全局庫和業(yè)務(wù)庫,其中業(yè)務(wù)庫又分為N多個(gè)庫,全局庫只放個(gè)別表方便開發(fā)。
這個(gè)時(shí)候 就需要一個(gè)全局DAO,此時(shí)我們的Mybatis就需要支持兩個(gè)DAO
兩個(gè)DAO(bizDao和globalDao)就需要有兩個(gè)sqlSessionFactory,bizSqlSessionFactory和globalSqlSessionFactory和兩個(gè)事物管理器transactionManager
<bean id="bizDao" class="com.xxx.dao.BizDao"><property name="sqlSessionFactory" ref="bizSqlSessionFactory"/></bean><bean id="globalDao" class="com.xxx.dao.GlobalDao"><property name="sqlSessionFactory" ref="globalSqlSessionFactory"/></bean> <bean id="bizSqlSessionFactory" parent="sqlSessionFactoryDefault" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="routingDataSource"/> </bean><bean id="globalSqlSessionFactory" parent="sqlSessionFactoryDefault" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="globalDataSource"/> </bean>根據(jù)請求動(dòng)態(tài)指定業(yè)務(wù)庫DataSource
分庫就是一個(gè)項(xiàng)目有多個(gè)數(shù)據(jù)庫,對Myabtis來說就有多個(gè)數(shù)據(jù)源(dataSource)根據(jù)你的請求 判斷應(yīng)該查詢哪個(gè)庫 從而指定動(dòng)態(tài)指定哪個(gè)數(shù)據(jù)源
可以繼承Spring的AbstractRoutingDataSource重寫接口中determineCurrentLookupKey()根據(jù)業(yè)務(wù)需求返回當(dāng)前的dbkey(哪個(gè)庫1、2、3、4。。。)
全局庫和業(yè)務(wù)庫事物管理器
因?yàn)槭挛锸腔赟ervice的,所以Service也建議分為全局Service和業(yè)務(wù)Service,根據(jù)Service類型(建議配個(gè)AOP全局處理 放到ThreadLocal中)
實(shí)現(xiàn)PlatformTransactionManager接口,接口中g(shù)etTransaction()方法可以動(dòng)態(tài)的返回指定的事物管理器(從上面的ThreadLocal中拿到當(dāng)前的事物管理器)
思考:為什么AbstractRoutingDataSource中多個(gè)DataSource不需要?jiǎng)討B(tài)配置事物管理器?
總結(jié):業(yè)務(wù)庫和全局庫有兩個(gè)不同的DataSource,其中業(yè)務(wù)庫的DataSource繼承Spring的AbstractRoutingDataSource,
Spring又分為了N個(gè)DataSource(對bizSqlSessionFactory而言 只有一個(gè)RoutingDataSource,RoutingDataSource里面有一個(gè)數(shù)據(jù)源集合)
全局的globalSqlSessionFactory也可以當(dāng)bizSqlSessionFactory中的AbstractRoutingDataSource的一個(gè)屬性 這么做雖然減少了配置,但是開發(fā)不直觀。
分表
上面的分庫的思路就是動(dòng)態(tài)指定DateSource和TransactionManager
分表:就是在Mybatis中寫一個(gè)攔截器 動(dòng)態(tài)的更改表名
1.攔截器
SqlSessionFactoryBean里面有個(gè)private Interceptor[] plugins;屬性 可以配置一些攔截器
我們自己定義的攔截器需要實(shí)現(xiàn)Interceptor接口
接口需要加以下注解
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}) })
2.在攔截器里面 我們需要?jiǎng)討B(tài)解析SQL和更改SQL
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}) }) public class MybatisInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {if (invocation.getTarget() instanceof StatementHandler) {RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();//通過反射拿到statement對象StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");BoundSql boundSql = delegate.getBoundSql();String sql = boundSql.getSql();String pageSql =sql+" limit 1 ";//操作sql//再通過反射把新sql設(shè)置進(jìn)去ReflectUtil.setFieldValue(boundSql, "sql", pageSql);}return invocation.proceed();}Mybatis四大對象以及插件原理
轉(zhuǎn)載于:https://www.cnblogs.com/ssskkk/p/11109597.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的如何用Mybatis分库分表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如果reporting server出现
- 下一篇: QT中的pro文件