一篇聊聊Mybatis插件开发

2023年 9月 21日 40.1k 0

Mybatis的插件,主要用于在执行sql前后,对sql进行封装加工,或者在sql执行后,对数据进行加工处理。常用于一些公共数据操作处理,例如:

  • 分页插件,在执行sql查询前增加分页参数
  • 多租户系统中,增加租户ID参数。
  • 增加更新时间、创建时间、更新人、创建人的参数信息。
  • 数据权限中,增加参数查询。
  • 插件开发过程

    确定需要拦截的签名

    指定需要拦截的方法,通过方法签名来指定,方法签名即指定哪个类的哪个方法+方法参数。这里的类不能随便写,只能从以下几个类中选,也就是说,MyBatis 插件可以拦截四大对象中的任意一个。

    • Executor 是执行 SQL 的全过程,包括组装参数,组装结果集返回和执行 SQL 过程,都可以拦截。
    • StatementHandler 是执行 SQL 的过程,我们可以重写执行 SQL 的过程。
    • ParameterHandler 是拦截执行 SQL 的参数组装,我们可以重写组装参数规则。
    • ResultSetHandler 用于拦截执行结果的组装,我们可以重写组装结果的规则。

    我们来看以下mybatisplus的插件配置的签名:

    @Intercepts(
        {
            @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
            @Signature(type = StatementHandler.class, method = "getBoundSql", args = {}),
            @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
            @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 MybatisPlusInterceptor implements Interceptor {
    //...
    }

    type指定四大类型中的任意一个,method指定拦截类型中方法,args指定方法参数。例如:

    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})

    指定了拦截StatementHandler的prepare方法,方法有两个参数,一个是Connection类型,另一个是Integer类型。

    public interface StatementHandler {
    
      Statement prepare(Connection connection, Integer transactionTimeout)
          throws SQLException;
          
          //....
          }

    插件接口定义

    在 MyBatis 中开发插件,需要实现 Interceptor 接口。接口的定义如下:

    public interface Interceptor {
     
      Object intercept(Invocation invocation) throws Throwable;
     
      Object plugin(Object target);
     
      void setProperties(Properties properties);
     
    }
    • intercept 方法:它将直接覆盖你所拦截对象原有的方法,因此它是插件的核心方法。通过 invocation 参数可以反射调度原来对象的方法。
    • plugin 方法:target 是被拦截对象,它的作用是给被拦截对象生成一个代理对象,并返回它。为了方便 MyBatis 使用 org.apache.ibatis.plugin.Plugin 中的 wrap 静态方法提供生成代理对象。
    • setProperties 方法:允许在 plugin 元素中配置所需参数,方法在插件初始化的时候就被调用了一次,然后把插件对象存入到配置中,以便后面再取出。

    实现插件

    创建个类实现Interceptor接口,并且在实现类上指定方法签名即可。

    最后需要在mybatis配置文件中配置插件

    
            
            
        

    最后建议看一下MybatisPlusInterceptor的实现,里面还使用到了责任链设计模式。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论