手写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)
posted @ 2020-07-10 14:51  snail灬  阅读(167)  评论(0编辑  收藏  举报