Skip to content

Commit

Permalink
升级 1.4.0 新增 delete update 全表操作禁止执行拦截器
Browse files Browse the repository at this point in the history
  • Loading branch information
青苗 committed Aug 16, 2016
1 parent 57dddc0 commit 3abc1a4
Showing 1 changed file with 149 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
* Copyright (c) 2011-2020, hubin ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.baomidou.mybatisplus.plugins;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Logger;

import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.executor.Executor;
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.session.Configuration;

import com.baomidou.mybatisplus.exceptions.MybatisPlusException;

/**
* <p>
* SQL 执行分析拦截器
* </p>
*
* @author hubin
* @Date 2016-08-16
*/
@Intercepts({@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class SqlExplainInterceptor implements Interceptor {
protected final Logger logger = Logger.getLogger("SqlExplainInterceptor");

/**
* 发现执行全表 delete update 语句是否停止执行
*/
private boolean stopProceed = false;

public Object intercept(Invocation invocation) throws Throwable {
/**
* 处理 DELETE UPDATE 语句
*/
MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
if (ms.getSqlCommandType() == SqlCommandType.DELETE || ms.getSqlCommandType() == SqlCommandType.UPDATE) {
Configuration configuration = ms.getConfiguration();
Object parameter = invocation.getArgs()[1];
BoundSql boundSql = ms.getBoundSql(parameter);
Executor exe = (Executor) invocation.getTarget();
Connection connection = exe.getTransaction().getConnection();

/**
* 执行 SQL 分析
*/
sqlExplain(configuration, ms, boundSql, connection, parameter);
}
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 ) throws Exception {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
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 query_statement = builder.build();
DefaultParameterHandler handler = new DefaultParameterHandler(query_statement, parameter, boundSql);
stmt = connection.prepareStatement(sqlExplain);
handler.setParameters(stmt);
rs = stmt.executeQuery();
while ( rs.next() ) {
if (!"Using where".equals(rs.getString("Extra"))) {
String tip = " Full table operation is prohibited. SQL: " + boundSql.getSql();
if (this.isStopProceed()) {
throw new MybatisPlusException(tip);
}
logger.severe(tip);
break;
}
}

} catch ( Exception e ) {
throw new MybatisPlusException(e);
} finally {
if ( rs != null ) {
rs.close();
rs = null;
}
if ( stmt != null ) {
stmt.close();
stmt = null;
}
}
}

public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
}
return target;
}

public void setProperties(Properties prop) {
// TODO
}

public boolean isStopProceed() {
return stopProceed;
}

public void setStopProceed(boolean stopProceed) {
this.stopProceed = stopProceed;
}

}

0 comments on commit 3abc1a4

Please sign in to comment.