公司新開發的系統數據量過大,須要進行分表處理,我在網上瀏覽一圈,選中了Shardbatis,緣由有二:sql
1.公司項目自己集成了Mybatis,而Shardbatis是其插件,引入方便;數據庫
2.Sharbatis十分輕便,只要稍微配置一下便可使用;數組
如何引入,百度一大堆,這裏再也不贅述,下面分析一下其原理:mybatis
Shardbatis說白了就是一個interceptor(攔截器),它的原理跟Mybatis的分頁插件(PageHelper)差很少,PageHelper其實也是依賴interceptor(攔截器)進行攔截將要發送到數據庫執行的sql,作進一步處理的插件。app
研究源碼能夠看到,PageHelper實現了Interceptor(攔截器)接口:this
@Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} )}) public class PageHelper implements Interceptor { private SqlUtil sqlUtil; private Properties properties; private SqlUtilConfig sqlUtilConfig; private boolean autoDialect = true; private boolean autoRuntimeDialect; private boolean closeConn = true; private Map<String, SqlUtil> urlSqlUtilMap = new ConcurrentHashMap(); public PageHelper() { } ...省略
Shardbatis也實現了Interceptor(攔截器)接口:google
@Intercepts({@Signature( type = StatementHandler.class, method = "prepare", args = {Connection.class} )}) public class ShardPlugin implements Interceptor { private static final Log log = LogFactory.getLog(com.google.code.shardbatis.plugin.ShardPlugin.class); public static final String SHARDING_CONFIG = "shardingConfig"; private static final ConcurrentHashMap<String, Boolean> cache = new ConcurrentHashMap(); public ShardPlugin() { } ...省略
咱們在初始化SqlSessionFactory的時候,能夠配置對應的攔截器,代碼以下:url
@Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) { SqlSessionFactoryBean bean = MybatisKit.newMybatisSessionFactory(dataSource, this.mybatisProperties); //初始化分表插件 ShardPlugin shardPlugin = new ShardPlugin(); //..省略 //初始化分頁插件 PageHelper pageHelper = new PageHelper(); //..省略 //根據本身須要攔截的順序,組裝數組 Interceptor[] plugins = new Interceptor[]{shardPlugin,pageHelper}; //將插件引入SqlSessionFactory bean.setPlugins(plugins); return bean; }
這樣,就能夠攔截Mybatis即將執行的Sql作進一步處理。插件
接下來,來分享一下,我集成Shardbatis時踩到的坑:3d
我依賴的是Shardbatis版本以下:
<dependency> <groupId>org.shardbatis</groupId> <artifactId>shardbatis</artifactId> <version>2.0.0B</version> </dependency>
當運行的時候報了以下錯誤:
這個錯誤讓我重複檢查了代碼N次,以及調試了N次仍然沒找到錯誤。在網上瘋狂百度搜索,最後在官網issue看到這個:
而後我翻一下我集成的ShardBatis插件源碼,發現:
這確實夠坑的,沒辦法,使用開源的東西,就得踩它的坑。最後,我重寫了ShardPlugin類,加上Integer.class ,完美解決問題:以下:
@Intercepts({@Signature( type = StatementHandler.class, method = "prepare", args = {Connection.class,Integer.class} )}) public class ShardPlugin implements Interceptor { private static final Log log = LogFactory.getLog(com.google.code.shardbatis.plugin.ShardPlugin.class); public static final String SHARDING_CONFIG = "shardingConfig"; private static final ConcurrentHashMap<String, Boolean> cache = new ConcurrentHashMap(); public ShardPlugin() { } ...省略
好了,本博客分享到此結束,謝謝。