Browse Source

优化代码,添加对于delete的操作,好修复数据

cxd 7 months ago
parent
commit
325631b96b

+ 7 - 0
framework/src/main/java/com/hys/app/framework/database/mybatisplus/MybatisAutoConfiguration.java

@@ -1,6 +1,7 @@
 package com.hys.app.framework.database.mybatisplus;
 
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.hys.app.framework.database.mybatisplus.base.DeleteOperationInterceptor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -10,6 +11,12 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class MybatisAutoConfiguration {
 
+    @Bean
+    public DeleteOperationInterceptor deleteOperationInterceptor() {
+        return new DeleteOperationInterceptor();
+    }
+
+
     @Bean
     public MetaObjectHandler defaultMetaObjectHandler() {
         return new DefaultDBFieldHandler(); // 自动填充参数类

+ 192 - 0
framework/src/main/java/com/hys/app/framework/database/mybatisplus/base/DeleteOperationInterceptor.java

@@ -0,0 +1,192 @@
+package com.hys.app.framework.database.mybatisplus.base;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+
+@Slf4j
+@Component
+@Intercepts({
+        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
+})
+public class DeleteOperationInterceptor implements Interceptor {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    private final ObjectMapper objectMapper;
+
+    public DeleteOperationInterceptor() {
+        this.objectMapper = new ObjectMapper();
+        this.objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+    }
+
+    @Override
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public Object intercept(Invocation invocation) throws Throwable {
+        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
+        Object parameter = invocation.getArgs()[1];
+
+        // 只处理删除操作
+        if (ms.getSqlCommandType() == SqlCommandType.DELETE) {
+            String methodId = ms.getId();
+            // 获取表名
+            String tableName = extractTableName(ms);
+
+            try {
+                String mapperClassName = methodId.substring(0, methodId.lastIndexOf("."));
+                Class<?> mapperClass = Class.forName(mapperClassName);
+                BaseMapper mapper = (BaseMapper) applicationContext.getBean(mapperClass);
+
+                // 获取要删除的数据和条件
+                Object deleteData = null;
+                String deleteCondition = "";
+
+                if (parameter instanceof Map) {
+                    Map<String, Object> paramMap = (Map<String, Object>) parameter;
+                    if (paramMap.containsKey("et")) {
+                        Object entity = paramMap.get("et");
+                        deleteData = mapper.selectById(getEntityId(entity));
+                        deleteCondition = "根据ID: " + getEntityId(entity);
+                    } else if (paramMap.containsKey("ew")) {
+                        Object wrapper = paramMap.get("ew");
+                        deleteCondition = extractDeleteCondition(wrapper);
+                        if (wrapper instanceof QueryWrapper) {
+                            deleteData = mapper.selectList((QueryWrapper) wrapper);
+                        } else if (wrapper instanceof LambdaQueryWrapper) {
+                            deleteData = mapper.selectList((LambdaQueryWrapper) wrapper);
+                        }
+                    } else if (paramMap.containsKey("array")) {
+                        Collection ids = (Collection) paramMap.get("array");
+                        deleteData = mapper.selectBatchIds(ids);
+                        deleteCondition = "批量删除ID: " + ids;
+                    }
+                } else if (parameter != null) {
+                    if (parameter instanceof Serializable) {
+                        deleteData = mapper.selectById((Serializable) parameter);
+                        deleteCondition = "根据ID: " + parameter;
+                    }
+                }
+
+                // 记录删除操作
+                String caller = getCallerInfo();
+                log.info("\n删除操作 - " +
+                                "\n调用者: {}" +
+                                "\n方法: {}" +
+                                "\n表名: {}" +
+                                "\n删除条件: {}" +
+                                "\n删除数据: {}",
+                        caller,
+                        methodId,
+                        tableName,
+                        deleteCondition,
+                        toJsonString(deleteData));
+
+            } catch (Exception e) {
+                log.error("获取删除数据失败", e);
+            }
+        }
+
+        return invocation.proceed();
+    }
+
+    private String extractTableName(MappedStatement ms) {
+        try {
+            // 从SQL语句中提取表名
+            String sql = ms.getBoundSql(null).getSql();
+            // DELETE FROM table_name ...
+            String[] parts = sql.split("\\s+");
+            if (parts.length >= 3) {
+                return parts[2].trim();
+            }
+        } catch (Exception e) {
+            log.warn("无法从SQL提取表名", e);
+        }
+        return "";
+    }
+
+    private String extractDeleteCondition(Object wrapper) {
+        try {
+            if (wrapper instanceof QueryWrapper) {
+                QueryWrapper qw = (QueryWrapper) wrapper;
+                Map<String, Object> paramNameValuePairs = qw.getParamNameValuePairs();
+                String targetSql = qw.getTargetSql();
+                // 替换参数占位符
+                for (Map.Entry<String, Object> entry : paramNameValuePairs.entrySet()) {
+                    targetSql = targetSql.replaceFirst("\\?", String.valueOf(entry.getValue()));
+                }
+                return targetSql;
+            } else if (wrapper instanceof LambdaQueryWrapper) {
+                LambdaQueryWrapper lqw = (LambdaQueryWrapper) wrapper;
+                Map<String, Object> paramNameValuePairs = lqw.getParamNameValuePairs();
+                String targetSql = lqw.getTargetSql();
+                // 替换参数占位符
+                for (Map.Entry<String, Object> entry : paramNameValuePairs.entrySet()) {
+                    targetSql = targetSql.replaceFirst("\\?", String.valueOf(entry.getValue()));
+                }
+                return targetSql;
+            }
+        } catch (Exception e) {
+            log.warn("提取删除条件失败", e);
+        }
+        return wrapper.toString();
+    }
+
+    private String getCallerInfo() {
+        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+        for (StackTraceElement element : stackTrace) {
+            String className = element.getClassName();
+            if (className.contains("service") && !className.contains("$")) {
+                return className + "." + element.getMethodName() + ":" + element.getLineNumber();
+            }
+        }
+        return "Unknown";
+    }
+
+    private Serializable getEntityId(Object entity) {
+        try {
+            // 尝试获取id字段
+            Field idField = entity.getClass().getDeclaredField("id");
+            idField.setAccessible(true);
+            return (Serializable) idField.get(entity);
+        } catch (Exception e) {
+            log.warn("获取实体ID失败", e);
+            return null;
+        }
+    }
+
+    private String toJsonString(Object obj) {
+        try {
+            return objectMapper.writeValueAsString(obj);
+        } catch (Exception e) {
+            log.warn("JSON序列化失败", e);
+            return String.valueOf(obj);
+        }
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+        // 可以添加配置项
+    }
+}

+ 0 - 126
framework/src/main/java/com/hys/app/framework/util/RemoveOperationAspect.java

@@ -1,126 +0,0 @@
-package com.hys.app.framework.util;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.springframework.stereotype.Component;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-@Aspect
-@Component
-@Slf4j
-public class RemoveOperationAspect {
-
-    private final ObjectMapper objectMapper;
-
-    public RemoveOperationAspect() {
-        this.objectMapper = new ObjectMapper();
-        // 设置美化输出
-        this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
-        // 空值也输出
-        this.objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
-    }
-
-    private String toJsonString(Object obj) {
-        try {
-            return obj != null ? objectMapper.writeValueAsString(obj) : "null";
-        } catch (Exception e) {
-            log.warn("JSON序列化失败: {}", e.getMessage());
-            return obj != null ? obj.toString() : "null";
-        }
-    }
-
-    @Around("execution(* com.baomidou.mybatisplus.extension.service.IService+.remove*(..)) || " +
-            "execution(* com.hys.app..*.remove*(..)) || " +
-            "execution(* com.hys.app..*.delete*(..))")
-    public Object logRemoveOperation(ProceedingJoinPoint point) throws Throwable {
-        String className = point.getTarget().getClass().getSimpleName();
-        String methodName = point.getSignature().getName();
-        Object[] args = point.getArgs();
-
-        // 获取调用者信息
-        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
-        String caller = "未知";
-        for (StackTraceElement element : stackTrace) {
-            if (!element.getClassName().contains("$Proxy")
-                    && !element.getClassName().contains("RemoveOperationAspect")
-                    && element.getClassName().startsWith("com.hys.app")) {
-                caller = element.getClassName() + "." + element.getMethodName() + ":" + element.getLineNumber();
-                break;
-            }
-        }
-
-        if (point.getTarget() instanceof IService) {
-            IService<?> service = (IService<?>) point.getTarget();
-            @SuppressWarnings("unchecked")
-            BaseMapper<Object> baseMapper = (BaseMapper<Object>) service.getBaseMapper();
-
-            try {
-                if (args.length > 0 && args[0] != null) {
-                    if (args[0] instanceof LambdaQueryWrapper) {
-                        // 如果是条件删除
-                        @SuppressWarnings("unchecked")
-                        LambdaQueryWrapper<Object> wrapper = (LambdaQueryWrapper<Object>) args[0];
-                        List<Object> dataList = baseMapper.selectList(wrapper);
-
-                        // 获取SQL和参数
-                        String sqlSegment = wrapper.getCustomSqlSegment();
-                        Map<String, Object> paramNameValuePairs = wrapper.getParamNameValuePairs();
-
-                        log.info("\n删除前的数据 - \n调用者: {}\n类: {}\n方法: {}\nSQL条件: {}\n参数: {}\n数据: {}",
-                                caller,
-                                className,
-                                methodName,
-                                sqlSegment,
-                                toJsonString(paramNameValuePairs),
-                                toJsonString(dataList));
-
-                    } else if (args[0] instanceof Collection) {
-                        // 如果是批量删除
-                        @SuppressWarnings("unchecked")
-                        Collection<? extends Serializable> ids = (Collection<? extends Serializable>) args[0];
-                        List<Object> dataList = baseMapper.selectBatchIds(ids);
-                        log.info("\n删除前的数据 - \n调用者: {}\n类: {}\n方法: {}\nID列表: {}\n数据: {}",
-                                caller,
-                                className,
-                                methodName,
-                                toJsonString(ids),
-                                toJsonString(dataList));
-
-                    } else if (args[0] instanceof Serializable) {
-                        // 如果是单个ID删除
-                        Serializable id = (Serializable) args[0];
-                        Object data = baseMapper.selectById(id);
-                        if (data != null) {
-                            log.info("\n删除前的数据 - \n调用者: {}\n类: {}\n方法: {}\nID: {}\n数据: {}",
-                                    caller,
-                                    className,
-                                    methodName,
-                                    id,
-                                    toJsonString(data));
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                log.error("\n记录删除数据失败 - \n调用者: {}\n类: {}\n方法: {}\n异常: {}",
-                        caller,
-                        className,
-                        methodName,
-                        e.getMessage(),
-                        e);
-            }
-        }
-
-        return point.proceed();
-    }
-}