• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

无信不立

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【mybatis源码学习】mybatis的插件功能

一、mybatis的插件功能可拦截的目标

org.apache.ibatis.executor.parameter.ParameterHandler
org.apache.ibatis.executor.resultset.ResultSetHandler
org.apache.ibatis.executor.statement.StatementHandler
org.apache.ibatis.executor.Executor

二、Mybatis的插件功能接入步骤

1、实现接口:org.apache.ibatis.plugin.Interceptor

2、实现类上需要添加注解@Intercepts和@Signature 用于描述要进行拦截的类接口和方法

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Intercepts {
  Signature[] value(); //要拦截的方法信息描述
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Signature {
  Class<?> type(); //要拦截的类的描述(接口)

  String method();//要拦截的方法名

  Class<?>[] args();//要拦截的方法名的参数列表的类型
}
View Code

3、将实现的Interceptor的类的对象,注入到Configuration的interceptorChain中

三、编写一个打印当前执行sql语句的插件案例

1、分析

依据mybatis的执行计划,StatementHandler 有一个方法 BoundSql getBoundSql(),其调用时机是向数据库申请连接,并向sql语句绑定参数时,从其内部获取sql语句。

 

故插件需要对StatementHandler进行拦截,并在其执行 getBoundSql语句时,从返回结果中获取sql语句,并打印

2、注意点

mybatis的插件功能使用的前提是对mybatis框架非常熟悉。

3、案例

@Intercepts(value = {@Signature(type = StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})})
public class SqlPrintInterceptor implements Interceptor {

    /**
     * 决定那个对象需要进行代理拦截
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        if(target instanceof StatementHandler){
            return Plugin.wrap(target, this);
        }
        return target;
    }

    /**
     * 执行代理的逻辑增强
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
         Object obj=invocation.proceed();
         RoutingStatementHandler handler= (RoutingStatementHandler) invocation.getTarget();
         System.out.println("current do sql=["+handler.getBoundSql().getSql()+"]");
        return obj;
    }

    /**
     * 设置当前代理的配置
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {

    }
}
View Code

 

interceptorChain

posted on 2019-09-08 18:58  无信不立  阅读(337)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3