ソースを参照

废除原有的sql分析拦截器.

nieqiurong 7 年 前
コミット
ad5f1fc2b5

+ 19 - 99
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/SqlExplainInterceptor.java

@@ -15,133 +15,56 @@
  */
 package com.baomidou.mybatisplus.extension.plugins;
 
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.util.Properties;
-
-import org.apache.ibatis.builder.StaticSqlSource;
 import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
-import org.apache.ibatis.mapping.BoundSql;
 import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.mapping.SqlCommandType;
 import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.plugin.Intercepts;
 import org.apache.ibatis.plugin.Invocation;
 import org.apache.ibatis.plugin.Plugin;
 import org.apache.ibatis.plugin.Signature;
-import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
+import org.apache.ibatis.reflection.SystemMetaObject;
 import org.apache.ibatis.session.Configuration;
-
-import com.baomidou.mybatisplus.annotation.DbType;
-import com.baomidou.mybatisplus.core.toolkit.Assert;
-import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
-import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.baomidou.mybatisplus.extension.toolkit.VersionUtils;
-
+import org.apache.ibatis.session.RowBounds;
+import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
 /**
  * <p>
- * SQL 执行分析拦截器【 目前只支持 MYSQL-5.6.3 以上版本 】
- * </p>
- * <p>
- * 使用解析器来替代该功能
- * com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser
+ * //todo 苗神来改个名
+ * 防止全表更新与删除
  * </p>
  *
  * @author hubin
  * @since 2016-08-16
  */
-@Deprecated
+@EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
 @Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
-public class SqlExplainInterceptor implements Interceptor {
+public class SqlExplainInterceptor extends AbstractSqlParserHandler implements Interceptor {
 
     private static final Log logger = LogFactory.getLog(SqlExplainInterceptor.class);
-    /**
-     * Mysql支持分析SQL的最小版本
-     */
-    private final String minMySQLVersion = "5.6.3";
-    /**
-     * 发现执行全表 delete update 语句是否停止执行
-     */
-    private boolean stopProceed = false;
+
+    private Properties properties;
 
     @Override
     public Object intercept(Invocation invocation) throws Throwable {
-        /**
-         * 处理 DELETE UPDATE 语句
-         */
-        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
-        if (ms.getSqlCommandType() == SqlCommandType.DELETE || ms.getSqlCommandType() == SqlCommandType.UPDATE) {
-            Executor executor = (Executor) invocation.getTarget();
-            Configuration configuration = ms.getConfiguration();
-            Object parameter = invocation.getArgs()[1];
-            BoundSql boundSql = ms.getBoundSql(parameter);
-            Connection connection = executor.getTransaction().getConnection();
-            String databaseVersion = connection.getMetaData().getDatabaseProductVersion();
-            if (GlobalConfigUtils.getDbType(configuration).equals(DbType.MYSQL)
-                && VersionUtils.compare(minMySQLVersion, databaseVersion)) {
-                logger.warn("Warn: Your mysql version needs to be greater than '5.6.3' to execute of Sql Explain!");
-                return invocation.proceed();
-            }
-            /**
-             * 执行 SQL 分析
-             */
-            sqlExplain(configuration, ms, boundSql, connection, parameter);
-        }
+        Object[] args = invocation.getArgs();
+        MappedStatement ms = (MappedStatement) args[0];
+        Object parameter = args[1];
+        Configuration configuration = ms.getConfiguration();
+        Object target = invocation.getTarget();
+        StatementHandler handler = configuration.newStatementHandler((Executor) target, ms, parameter, RowBounds.DEFAULT, null, null);
+        this.sqlParser(SystemMetaObject.forObject(handler));
         return invocation.proceed();
     }
 
-    /**
-     * <p>
-     * 判断是否执行 SQL
-     * </p>
-     *
-     * @param configuration
-     * @param mappedStatement
-     * @param boundSql
-     * @param connection
-     * @param parameter
-     * @return
-     * @throws Exception
-     */
-    protected void sqlExplain(Configuration configuration, MappedStatement mappedStatement, BoundSql boundSql,
-                              Connection connection, Object parameter) {
-        StringBuilder explain = new StringBuilder("EXPLAIN ");
-        explain.append(boundSql.getSql());
-        String sqlExplain = explain.toString();
-        StaticSqlSource sqlsource = new StaticSqlSource(configuration, sqlExplain, boundSql.getParameterMappings());
-        MappedStatement.Builder builder = new MappedStatement.Builder(configuration, "explain_sql", sqlsource,
-            SqlCommandType.SELECT);
-        builder.resultMaps(mappedStatement.getResultMaps()).resultSetType(mappedStatement.getResultSetType())
-            .statementType(mappedStatement.getStatementType());
-        MappedStatement queryStatement = builder.build();
-        DefaultParameterHandler handler = new DefaultParameterHandler(queryStatement, parameter, boundSql);
-        try (PreparedStatement stmt = connection.prepareStatement(sqlExplain)) {
-            handler.setParameters(stmt);
-            try (ResultSet rs = stmt.executeQuery()) {
-                while (rs.next()) {
-                    if (!"Using where".equals(rs.getString("Extra"))) {
-                        Assert.isFalse(this.isStopProceed(),
-                            "Error: Full table operation is prohibited. SQL: " + boundSql.getSql());
-                        break;
-                    }
-                }
-            }
-
-
-        } catch (Exception e) {
-            throw ExceptionUtils.mpe(e);
-        }
-    }
-
     @Override
     public Object plugin(Object target) {
         if (target instanceof Executor) {
@@ -152,9 +75,6 @@ public class SqlExplainInterceptor implements Interceptor {
 
     @Override
     public void setProperties(Properties prop) {
-        String stopProceed = prop.getProperty("stopProceed");
-        if (StringUtils.isNotEmpty(stopProceed)) {
-            this.stopProceed = Boolean.valueOf(stopProceed);
-        }
+        this.properties = prop;
     }
 }