基于mybatis拦截器实现的一款简易影子表自动切换插件

1,433 阅读2分钟

因工作需要,小编近期基于mybatis拦截器开发了一款简易影子表自动切换插件,可以根据配置实现动态修改表名,即将对原source table表的操作自动切换到对target table表的操作。该插件既可以支持对简单的单表操作,也可以支持复杂的多表联合操作。

源码地址:mybatis影子表切换插件

下面来说说如何实现mybatis以自定义插件?

1. MyBatis核心部件

从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个:

name description
SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能 Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护 StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合 ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数
ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatement MappedStatement维护了一条节点的封装
SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回 BoundSql 表示动态生成的SQL语句以及相应的参数信息
Configuration MyBatis所有的配置信息都维持在Configuration对象之中

2. MyBatis核心部件的层次结构关系

3. 如何扩展?

基于MyBatis Interceptor插件机制

  • 拦截器(Interceptor)在 MyBatis 中被当做插件(plugin)对待,官方文档提供了Executor(拦截执行器的方法),ParameterHandler(拦截参数的处理),ResultSetHandler(拦截结果集的处理),StatementHandler(拦截Sql语法构建的处理)共4种,并且提示“这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看MyBatis发行包中的源代码”
  • 拦截器的使用场景主要是更新数据库的通用字段,分库分表,加解密等的处理
  • 我们使用Interceptor机制对执行的Sql进行拦截并追加逻辑,示例代码如下:
    /**
     * @author zhangjb
     * @ClassName: MyInterceptor <br>
     * @Description: 测试mybatis拦截器 <br>
     * <p>
     * 拦截方法 {@link org.apache.ibatis.executor.statement.StatementHandler#prepare(Connection, Integer)}
     */
    @Slf4j
    @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
    public class MyInterceptor implements Interceptor {
    
        .....
        
        @Override
            public Object intercept(Invocation invocation) throws Throwable {
                try {
                    // do something
                } catch (Throwable throwable) {
                    log.warn("MyInterceptor: {}", Throwables.getStackTraceAsString(throwable));
                }
                return invocation.proceed();
            }
        }
    
        ......
    }

4. 关于兼容性

另外还需要注意的是mybatis-spring、mybatis、spring这三个包的兼容性,官方给出的兼容方案如下: