公司新开发的系统数据量过大,须要进行分表处理,我在网上浏览一圈,选中了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() { } ...省略
好了,本博客分享到此结束,谢谢。