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);
}
}