How does Mybatis-plus use interceptors to get SQL and parse it?

1. Custom interceptor

package com.tigeriot.mqtt.config.mybatis;

import cn.hutool.json.JSONUtil;
import com.tigeriot.mqtt.common.CacheDev;
import com.tigeriot.mqtt.common.CacheMQ;
import com.tigeriot.mqtt.entity.log.DevLog;
import com.tigeriot.mqtt.service.DevLogService;
import com.tigeriot.mqtt.util.JsonUtils;
import com.tigeriot.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();
        //Get table name
        String tableName = SQLParseUtils.getTableName(sql);
        if (tableName==null){
            throw new Exception("Table name parsing failed");
        }


        //If it is a log, let it pass without adding a log.
        if (tableName.equalsIgnoreCase("DevLog")){
            return invocation.proceed();
        }


        long start =System.currentTimeMillis();
        //Perform SQL operations
        Object result = invocation.proceed();

        long end =System.currentTimeMillis();





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

        //Judge sql type
        String sqlType = SQLParseUtils.parseSQLType(sql);

        if (sqlType==null){
            throw new Exception("Log SQL parsing failed");
        }



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




        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("Successfully placed in the queue, asynchronous execution log stored in the database");
        }



        return result;
    }

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

    @Override
    public void setProperties(Properties properties) {
        // You can configure the properties of the plug-in here
    }


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




}

2. mybatis-config.xml configuration file

<?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 core configuration file-->
<configuration>
    <!-- Configure interceptor -->
    <plugins>
        <plugin interceptor="com.tigeriot.mqtt.config.mybatis.OperationLogInterceptor">
            <!-- You can configure the properties of the plug-in here -->
        </plugin>
    </plugins>

</configuration>

3. Springboot configuration this mybatis-config.xml

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

4. SQL Tools

package com.tigeriot.mqtt.util;
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;

        // Regular expression matches INSERT, UPDATE and DELETE statements
        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 is illegal");
// }
// } 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);
    }

}