手写Mybatis插件
业务功能:
把一个表按照月份分为12个,命名user_01、user_02、....user_12。
Mapper.xml中只配置一个SQL:
select * from user where age = #{age}
输入当前月份查询的时候,自动把逻辑表名改成对应的月份表。例如输入202005,此时需要把表名修改为
select * from user_05 where age=5
实现:
注册插件:
mybatis-config.xml添加:
<plugin interceptor="com.xx.helper.QuerySliceInterceptor"/>
插件(一个实现当前功能的简单插件):
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class QuerySliceInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
BoundSql boundSql;
//由于逻辑关系,只会进入一次
if (args.length == 4) {
//4 个参数时
boundSql = ms.getBoundSql(parameter);
} else {
//5 个参数时(这里去掉了缓存 CacheKey)
boundSql = (BoundSql) args[5];
}
//反射获取动态参数
String sql = boundSql.getSql();
String querySql = getQuerySql(sql, parameter);
parameter = Integer.valueOf(String.valueOf(parameter).substring(4));
BoundSql pageBoundSql = new BoundSql(ms.getConfiguration(), querySql, boundSql.getParameterMappings(), parameter);
List resultList = executor.query(ms, parameter, rowBounds, resultHandler, null, pageBoundSql);
return resultList;
}
@Override
public Object plugin(Object o) {
return Plugin.wrap(o, this);
}
@Override
public void setProperties(Properties properties) {
}
public String getQuerySql(String sql, Object param) {
String[] src = sql.split(" ");
param = String.valueOf(param).substring(4);
String tableName = (src[3] + "_" + param);
src[3] = tableName;
sql = StringUtils.join(src, " ");
return sql;
}
}
测试类:
public class Test {
@Autowired
private UserService userService;
@Test
public void userTest() {
User user = userService.selectOne(202005);
System.out.println(user);
}
}
结果:
User(id=1, name=小明, age=5)