【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();//要拦截的方法名的参数列表的类型
}

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) {

    }
}

interceptorChain

原文地址:https://www.cnblogs.com/shangxiaofei/p/11487852.html

时间: 2024-08-24 18:27:42

【mybatis源码学习】mybatis的插件功能的相关文章

Mybatis源码学习记录

一.对源码先上一个结构图: 源代码主要在org.apache.ibatis目录下,18个包,其中在应用中主要的包有:builder.session.cache.type.transaction.datasource.jdbc.mapping,提供支撑服务的包有annotation.binding.io.logging.plugin.reflection.scripting.exception.executor.parsing 二.从使用入手 MyBatis使用的三板斧是SqlSessionFac

mybatis专题(三)-----mybatis源码学习

源码分析概述 源码包分析 下载地址 MyBatis 源码下载地址:https://github.com/mybatis/mybatis-3 导入过程 1. 下载MyBatis的源码 2. 检查maven的版本,必须是3.25以上,建议使用maven的最新版本 3. mybatis的工程是maven工程,在开发工具中导入,工程必须使用jdk1.8以上版本: 4. 把mybatis源码的pom文件中true,全部改为false,或者直接删除这行: 5. 在工程目录下执行 mvn clean inst

MyBatis源码分析-MyBatis初始化流程

MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录.如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA新建MyBatis源码工程. MyBatis初始化的过程也就是创建Configura

mybatis源码学习: 编译的方法

mybatis3用了一段时间,抽出时间来研究一下.具体用法参考官方文档就行,源码在这里.mybatis相对而言,规模较小,可以从中学习如何编写高质量的java项目. mybatis3使用maven管理.方法很简单. 1,mybatis3项目依赖父项目,所以先clone这个项目,然后mvn install 就可以了.就会安装到本地仓库. 2.再mvn install  mybatis-3对应的项目就成功了

Mybatis 源码学习系列

前言 很久以前,我们学习了Java,从一个控制台的 Hello world .开始,我们进入了面向对象的世界. 然后由学习了SQL语言,可以写出SQL语句来将尘封在硬盘之下的数据库数据,展现出来. 后来我们使用JDBC 来操作数据库,进行各种增删改查.然而,我们对于原生的JDBC并不满意,写起来很不爽-- 于是,我们使用了Mybatis,写了一个又一个的mapper,无论需求怎么变动,无论情况怎么复杂多变.对于我们来说只是增加mapper,修改xml中的sql就好了. 从此,一切似乎很简单,水到

【mybatis源码学习】mybatis的参数处理

一.mybatis的参数处理以及参数取值 1.单个参数 mybatis不做任何处理 取值方式: ? #{参数名/任意名} <!-- Employee getEmpById(Integer id); --> <select id="getEmpById" resultType="com.mxc.bean.Employee"> select * from employee where id=#{id} </select> 2.多个参数

【mybatis源码学习】利用maven插件自动生成mybatis代码

[一]在要生成代码的项目模块的pom.xml文件中添加maven插件 <!--mybatis代码生成器--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <dependencies>

mybatis源码学习: 动态代理的应用(慢慢改)

动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system.currenttimemillis(); 调用原来的方法 long last=system.currenttimemillis(); 如果每个方法都人工加入实在有点不爽,动态代理出场了.动态代理利用字节码技在原来对应的类的子节码进行重写,添加对应的逻辑. 主流的动态代理实现技术主流如下:JDK 和C

mybatis源码学习(二):SQL执行

从上一篇文章中,我们了解到MapperMethod将SQL的执行交给了sqlsession处理.今天我们继续往下看处理的过程. SqlSession接口除了提供获取Configuration,Mapper的方法之外,主要的作用就是提供增删该查的方法. /** * Copyright 2009-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License&q