hand-sql-mybatis插件-获取mybatis的SQL及参数

Mybatis四大核心组件

Executor

执行和数据库相关的方法(不是指具体的SQL语句的执行)

StatementHandler

执行和数据库相关的具体SQL语句

ParameterHandler

mybatis提供的参数处理器,映射参数。比如将传入的对象,映射到具体的SQL参数上

ResultSetHandler

对于查询数据结果集的映射和处理

而我们的插件应该插入到StatementHandler的上面

package com.hand.mybatis.demo.plugins;

import com.hand.mybatis.demo.entity.MybatisSql;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * @author dell
 */
@Intercepts({@Signature(
        type= StatementHandler.class, //拦截的目标是四大对象的哪个对象,这里选择的是StatementHandler
        method = "prepare",//StatementHandler中的哪一个方法
        args = {Connection.class,Integer.class})}) //prepare方法中的所需的参数

public class MyPlugins implements Interceptor {

    /**
     *
     * @param invocation :整个拦截器的一个封装
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
        //要在SQL执行之前,执行一条插入数据库的语句
        Connection connection = (Connection)invocation.getArgs()[0];
      
        /**
         * 获取到执行的SQL语句
         */
        String sql = statementHandler.getBoundSql().getSql();
        System.out.println("原始的SQL:"+sql);
        /**
         * 获取到SQL执行的参数
         */
        ParameterHandler parameterHandler = statementHandler.getParameterHandler();
        String sqlParam = parameterHandler.getParameterObject().toString();
        System.out.println("SQL的参数:"+ sqlParam);
        //在执行SQL之前,还可以更改原SQL,比如说增加limit分页
        String insertDbSql = "insert into mybatissql(sql_insert,sql_param,create_time) values("+"'"+sql+"'"+','+"\""+sqlParam+"\""+','+"now())";
        System.out.println("插入语句为:"+insertDbSql);
        PreparedStatement preparedStatement = connection.prepareStatement(insertDbSql);
        preparedStatement.execute();
        connection.commit();
        //执行完逻辑之后,推进拦截链
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //target :目标对象
        //interceptor:代理对象
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

知识点:

  1. 注解上的type,表示你要拦截的对象,这里选择的是StatementHandler,因为StatementHandler操作的是具体的SQL,在该组件前进行拦截,我们可以获取到SQL和SQL的参数
  2. method是指StatementHandler的方法,选择的是prepare方法
  3. args自然就是指prepare方法的参数

更新数据库的操作,需要commit,关于mybatis的插件的标签,需要按照一定的顺序来配置

猜你喜欢

转载自blog.csdn.net/awodwde/article/details/118702373