实现原理
- 使用SpringAOP拦截方法 + 实现
Interceptor
拦截SQL + ThreadLocal存储分表信息 - 首先在
ShardingTableAspect
配置@Pointcut("execution(* com.xxx.xxx.dao.sharding.*.*(..))")
用来拦截sharding目录下的所有方法 - 在环绕通知
daoAround
中获取被拦截方法参数中@ShardingKey
注解对应的field的值,和类注解@TableSharding
定义的tableName
存入ThreadLocal
中 ShardingInterceptor
实现Interceptor
,在mybatis组装完SQL会进入intercept
,在方法中获取ThreadLocal
中的分表信息,根据分表信息替换为新的表名
注意事项
- 配置插件时,Order顺序是有意义的,如果先
shardingInterceptor
没有办法拦截select count()
因为这条语句是paginationInterceptor
生成的,如果如果先paginationInterceptor
,获取statementHandler
一定要进行递归获取真正的对象,因为select count()
是属于被代理的
@Bean
@Order(102)
public ShardingInterceptor shardingInterceptor() {
return new ShardingInterceptor();
}
/**
* 分页插件
*/
@Bean
@Order(101)
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}