Mybatis-plus 怎么使用拦截器拿到SQL,并解析

1、自定义拦截器



import cn.hutool.json.JSONUtil;
import com.mqtt.common.CacheDev;
import com.mqtt.common.CacheMQ;
import com.mqtt.entity.log.DevLog;
import com.mqtt.service.DevLogService;
import com.mqtt.util.JsonUtils;
import com.mqtt.util.SQLParseUtils;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

@Intercepts({
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class OperationLogInterceptor implements Interceptor{




    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];

        Object parameter = invocation.getArgs()[1];

        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        //sql
        String sql = boundSql.getSql();
        //获取表名
        String tableName = SQLParseUtils.getTableName(sql);
        if (tableName==null){
            throw new Exception("表名解析失败");
        }


        //如果是日志,就放行,不用加日志
        if (tableName.equalsIgnoreCase("DevLog")){
            return invocation.proceed();
        }


        long start =System.currentTimeMillis();
        // 执行 SQL 操作
        Object result = invocation.proceed();

        long end =System.currentTimeMillis();





        //参数
        String param = JsonUtils.getJson(parameter);
        System.out.println("json:    "+param);

        //判断sql类型
        String sqlType = SQLParseUtils.parseSQLType(sql);

        if (sqlType==null){
            throw new Exception("日志SQL解析失败");
        }



        sql= sql.replaceAll("\n", "");




        Date createTime =new Date();

        Long executeTime=end-start;


        DevLog devLog = new DevLog(null, tableName, sqlType, sql, param, executeTime, createTime);
        System.out.println("devLog:"+devLog);


        boolean offer = CacheMQ.logQueue.offer(devLog);
        if (offer){
            System.out.println("成功放入队列,异步执行日志存入数据库");
        }



        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以在此处配置插件的属性
    }


//    @Override
//    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        OperationLogInterceptor.applicationContext=applicationContext;
//        OperationLogInterceptor.devLogService=applicationContext.getBean(DevLogService.class);
//
//    }




}

2、mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心配置文件-->
<configuration>
    <!-- 配置拦截器 -->
    <plugins>
        <plugin interceptor="com.tigeriot.mqtt.config.mybatis.OperationLogInterceptor">
            <!-- 可以在此处配置插件的属性 -->
        </plugin>
    </plugins>

</configuration>

3、springboot配置 这个 mybatis-config.xml

mybatis-plus:
  configLocation: classpath:mybatis/mybatis-config.xml

4、SQL工具类


import cn.hutool.json.JSONUtil;

import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class SQLParseUtils {



    public static String parseSQLType(String sql){
        if (sql==null){
            return null;
        }

        String type = sql.split(" ")[0];
       if (type.equalsIgnoreCase("INSERT")){
           return "INSERT";
       } else if (type.equalsIgnoreCase("UPDATE")) {
           return "UPDATE";
       } else if (type.equalsIgnoreCase("DELETE")) {
           return "DELETE";
       }else {
           return null;
       }

    }


    public static String getTableName(String sql) {
        String tableName = null;

        // 正则表达式匹配 INSERT、UPDATE 和 DELETE 语句
        String regex = "(?i)(?:INSERT\\s+INTO|UPDATE|DELETE\\s+FROM)\\s+(\\w+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(sql.trim());

        if (matcher.find()) {
            tableName = matcher.group(1);
        }

        return tableName;
    }


    public static String getParam(String json,String type) throws Exception {
//        try {
//            if (type.equalsIgnoreCase("INSERT")){
//
//
//
//            } else if (type.equalsIgnoreCase("UPDATE")) {
//                Map bean = JSONUtil.parseObj(json).toBean(Map.class);
//                Map<String,Object> o = (Map<String, Object>) bean.get("ew");
//                Object o1 = o.get("sqlSet");
//                return   JsonUtils.getJson(o1);
//
//
//            }else if (type.equalsIgnoreCase("DELETE")){
//                Map bean = JSONUtil.parseObj(json).toBean(Map.class);
//                Map<String,Object> o = (Map<String, Object>) bean.get("ew");
//                Object o1 = o.get("paramNameValuePairs");
//                return   JsonUtils.getJson(o1);
//
//
//            }else {
//               throw new Exception("type不合法");
//            }
//        } catch (Exception e) {
//            System.out.println(e.getMessage());
//            return null;
//        }

        return null;

    }




    public static void main(String[] args) {
        String tableName = getTableName("INSERT INTO orders (customer_id, product_id, quantity) VALUES (789, 123, 5)");
        System.out.println(tableName);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值