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