spring aop实现监听业务删除/修改记录恢复

实现上述功能需要注解进行协助

@Aspect
@Component
public class SqlLoggingAspect {


    @Around("execution(* javax.sql.DataSource.getConnection(..))")
    @Order
    public Object aroundGetConnection(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            HttpServletRequest httpServletRequest = RequestUtil.GetRequest();
            if (httpServletRequest != null) {//每次只会获取一次session
                Callable<Connection> callable = () -> {
                    PreparedStatementHandler.threadLocalVariable = new ThreadLocal<>();
                    try {
                        return (Connection) joinPoint.proceed();
                    } catch (Throwable e) {
                        throw new RuntimeException(e);
                    }
                };
                return createProxy(callable);
            }
        } catch (Exception e) {
        }
        return joinPoint.proceed();
    }


    public Object createProxy(Callable<Connection> callable) throws Exception {
        Connection connection = callable.call();
        return Proxy.newProxyInstance(
                Connection.class.getClassLoader(),
                new Class[]{Connection.class},
                new SqlLoggingHandler(connection)
        );
    }

}
public class SqlLoggingHandler implements InvocationHandler {
    private final Connection realConnection;

    public SqlLoggingHandler(Connection realConnection) {
        this.realConnection = realConnection;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("prepareStatement".equals(method.getName())) {
            PreparedStatement preparedStatement = (PreparedStatement) method.invoke(realConnection, args);
            return Proxy.newProxyInstance(
                    preparedStatement.getClass().getClassLoader(),
                    preparedStatement.getClass().getInterfaces(),
                    new PreparedStatementHandler(preparedStatement)
            );
        } else {
            return method.invoke(realConnection, args);
        }
    }

}

public class PreparedStatementHandler implements InvocationHandler {
    private final PreparedStatement realPreparedStatement;
    private ArrayList<Object> parameters = new ArrayList<>();
    public static ThreadLocal<List<HashMap<String, Object>>> threadLocalVariable = new ThreadLocal<>();
    public static ThreadLocal<String> threadLocalId = new ThreadLocal<>();

    public PreparedStatementHandler(PreparedStatement realPreparedStatement) {
        this.realPreparedStatement = realPreparedStatement;
    }


    private static Map<String, String> extractKeyValuePairs(Expression expression) {
        Map<String, String> keyValuePairs = new HashMap<>();
        if (expression instanceof BinaryExpression) {
            BinaryExpression binaryExpression = (BinaryExpression) expression;
            if (binaryExpression.getLeftExpression() instanceof Column && binaryExpression.getRightExpression() instanceof StringValue) {
                Column column = (Column) binaryExpression.getLeftExpression();
                StringValue stringValue = (StringValue) binaryExpression.getRightExpression();
                keyValuePairs.put(column.getColumnName(), stringValue.getValue());
            } else if (binaryExpression.getLeftExpression() instanceof BinaryExpression) {
                keyValuePairs.putAll(extractKeyValuePairs(binaryExpression.getLeftExpression()));
            } else if (binaryExpression.getRightExpression() instanceof BinaryExpression) {
                keyValuePairs.putAll(extractKeyValuePairs(binaryExpression.getRightExpression()));
            }
        } else if (expression instanceof AndExpression) {
            AndExpression andOrExpression = (AndExpression) expression;
            keyValuePairs.putAll(extractKeyValuePairs(andOrExpression.getLeftExpression()));
            keyValuePairs.putAll(extractKeyValuePairs(andOrExpression.getRightExpression()));
        } else if (expression instanceof OrExpression) {
            OrExpression andOrExpression = (OrExpression) expression;
            keyValuePairs.putAll(extractKeyValuePairs(andOrExpression.getLeftExpression()));
            keyValuePairs.putAll(extractKeyValuePairs(andOrExpression.getRightExpression()));
        }

        return keyValuePairs;
    }

    public static String findMainTableName(List<HashMap<String, Object>> hashMaps) {
        HashMap<String, Integer> weightHashMap = new HashMap<>();
        String mainTableName = "";
        Integer max = 0;
        for (HashMap<String, Object> hashMap : hashMaps) {
            Map<String, Object> stringObjectMap = TypeConvert.FromMapJson(TypeConvert.ToString(hashMap.get("whereSets")));
            if (stringObjectMap != null && stringObjectMap.containsKey(BaseModel.F_id.toUpperCase())) {//是否有id
                String tableName = TypeConvert.ToString(hashMap.get("tableName"));
                if (weightHashMap.containsKey(tableName)) {
                    Integer tableWidght = weightHashMap.get("tableName");
                    weightHashMap.put(tableName, tableWidght + 1);
                } else {
                    weightHashMap.put(tableName, 1);
                }
                if (weightHashMap.get(tableName) > max) {
                    mainTableName = tableName;
                    max = weightHashMap.get(tableName);
                }
            }
        }

        for (HashMap<String, Object> hashMap : hashMaps) {
            String tableName = TypeConvert.ToString(hashMap.get("tableName"));
            Class<BaseModel> baseModelClass = SqlCache.GetClassByTableName(tableName);
            if (baseModelClass != null) {
                Field[] declaredFields = baseModelClass.getDeclaredFields();
                Map<String, Object> whereMap = TypeConvert.FromMapJson(TypeConvert.ToString(hashMap.get("whereSets")));
                for (Field declaredField : declaredFields) {
                    if (declaredField.isAnnotationPresent(XColumn.class)) {
                        XColumn annotation = declaredField.getAnnotation(XColumn.class);
                        if (annotation != null) {
                            if (StrUtil.isNotEmpty(annotation.foreignTable()) && whereMap.containsKey(declaredField.getName().toUpperCase())) {
                                if (weightHashMap.containsKey(annotation.foreignTable())) {
                                    weightHashMap.compute(annotation.foreignTable(), (k, tableWidght) -> tableWidght + 1);
                                    if (weightHashMap.get(annotation.foreignTable()) > max) {
                                        mainTableName = annotation.foreignTable();
                                        max = weightHashMap.get(annotation.foreignTable());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return mainTableName;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        HashMap<String, Object> objMap = new HashMap<>();
        boolean isSave = false;
        if (threadLocalVariable.get() == null) {
            threadLocalVariable.set(new ArrayList<>());
            threadLocalId.set(BaseModel.GetUniqueId());
        }
        if (method.getName().startsWith("set")) {
            parameters.add(args[1]);
        } else if ("executeQuery".equals(method.getName()) || "executeUpdate".equals(method.getName()) || "executeBatch".equals(method.getName())) {
            String sql = realPreparedStatement.toString(); // 默认SQL没有参数
            try {
                sql = realPreparedStatement.unwrap(PreparedStatement.class).toString();
            } catch (SQLException e) {
                // Ignore
            }
            objMap.put("sql", sql);
            for (int i = 0; i < parameters.size(); i++) {
                sql = sql.replaceFirst("\\?", parameters.get(i).toString());
            }
            objMap.put("param", parameters);
            objMap.put("paramSql", sql);//sql param
            if (!sql.toUpperCase().contains(SCLS删除历史.F_TableName)) {
                if (sql.toUpperCase().split(":")[1].trim().matches("(DELETE).*")) {
                    Statement parse = CCJSqlParserUtil.parse(sql.toUpperCase().split(":", 2)[1].trim());
                    if (parse instanceof Delete) {
                        isSave = true;
                        Delete delete = (Delete) parse;
                        Map<String, String> retMap = extractKeyValuePairs(delete.getWhere());
                        objMap.put("tableName", delete.getTable().getName());
                        objMap.put("type", "delete");//更新内容
                        objMap.put("whereSets", TypeConvert.ToJson(retMap));
                        String selectSql = sql.toUpperCase().split(":")[1].trim().replaceFirst("DELETE", "SELECT *");
                        final List<Map<String, Object>> query = new ArrayList<>();
                        DBSession.GetSession().doWork(db -> {
                            List<Map<String, Object>> _query = new QueryRunner().query(db.getOrOpenConnection(), selectSql, new SqlListHandler(), db.handleSqlParams(new Object[]{}));
                            query.addAll(_query);
                        });
                        objMap.put("oriObjects", TypeConvert.ToJson(query));
                    }
                } else if (sql.toUpperCase().split(":", 2)[1].trim().matches("(UPDATE).*")) {
                    Statement parse = CCJSqlParserUtil.parse(sql.toUpperCase().split(":", 2)[1].trim());
                    if (parse instanceof Update) {
                        isSave = true;
                        Update update = (Update) parse;
                        objMap.put("tableName", update.getTable().getName());//获取表名
                        if (StrUtil.isNotEqual(update.getTable().getName(), SCLS删除历史.F_TableName)) {
                            for (HashMap<String, Object> retMap : threadLocalVariable.get()) {
                                if (StrUtil.isEqual(TypeConvert.ToString(retMap.get("type")), "update")
                                        && StrUtil.isEqual(TypeConvert.ToString(retMap.get("tableName")), update.getTable().getName())
                                        && StrUtil.isEqual(TypeConvert.ToString(retMap.get("oriObjects")), TypeConvert.ToJson(update.getUpdateSets()))) {
                                    isSave = false;
                                }
                            }
                            if (isSave) {
                                objMap.put("updateSets", TypeConvert.ToJson(update.getUpdateSets()));//更新内容
                                objMap.put("type", "update");//更新内容
                                Class<BaseModel> baseModelClass = SqlCache.GetClassByTableName(update.getTable().getName());
                                if (baseModelClass != null) {
                                    Map<String, String> retMap = extractKeyValuePairs(update.getWhere());
                                    objMap.put("whereSets", TypeConvert.ToJson(retMap));
                                    String selectSql = "SELECT * FROM " + update.getTable().getName() + " WHERE " + update.getWhere();
                                    final List<Map<String, Object>> query = new ArrayList<>();
                                    DBSession.GetSession().doWork(db -> {
                                        List<Map<String, Object>> _query = new QueryRunner().query(db.getOrOpenConnection(), selectSql, new SqlListHandler(), db.handleSqlParams(new Object[]{}));
                                        query.addAll(_query);
                                    });
                                    objMap.put("oriObjects", TypeConvert.ToJson(query));
                                }
                            }
                        } else {
                            isSave = false;
                        }
                    }
                }
            }
            if (isSave) {//
                List<HashMap<String, Object>> hashMaps = threadLocalVariable.get();
                hashMaps.add(objMap);
                threadLocalVariable.set(hashMaps);
                SCLS删除历史 scls删除历史 = new SCLS删除历史();
                scls删除历史.id = threadLocalId.get();
                scls删除历史.删除内容 = TypeConvert.ToJson(hashMaps);
                scls删除历史.删除时间 = new Date();
                scls删除历史.主表名 = findMainTableName(hashMaps);
                if (GlobalValues.GetSessionUser() != null) {
                    scls删除历史.删除人员id = GlobalValues.GetSessionUser().id;
                }
                scls删除历史.Save();
            }
            parameters.clear();
        }
        return method.invoke(realPreparedStatement, args);
    }
}
 @RequestMapping(value = "/rollback", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String rollback(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        String id = RequestUtil.GetString(request, BaseModel.F_id);
        SCLS删除历史 scls删除历史 = SCLS删除历史.GetObjectById(SCLS删除历史.class, id);
        String error_msg = "";
        if (scls删除历史 != null) {
            List<Map<String, Object>> maps = TypeConvert.FromListMapJson(scls删除历史.删除内容);
            for (Map<String, Object> map : maps) {
                String tableName = TypeConvert.ToString(map.get("tableName"));
                String oriObjectsJson = TypeConvert.ToString(map.get("oriObjects"));
                if (StrUtil.isNotEmpty(tableName) && StrUtil.isNotEmpty(oriObjectsJson)) {
                    List<Map<String, Object>> objMapS = TypeConvert.FromListMapJson(oriObjectsJson);
                    Class<BaseModel> baseModelClass = SqlCache.GetClassByTableName(tableName);
                    if (baseModelClass != null) {
                        for (Map<String, Object> objMap : objMapS) {
                            BaseModel baseModel = baseModelClass.newInstance();
                            baseModel.SetValuesByMap(objMap);
                            baseModel.Save();
                        }
                        scls删除历史.Delete();
                        return AjaxResult.True("恢复成功").ToJson();
                    } else {
                        error_msg = tableName + "字节码文件不存在";
                    }
                } else {
                    error_msg = "tableName或oriObjects为空";
                }
            }
        }
        return AjaxResult.False("恢复失败:" + error_msg).ToJson();
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值