您的位置:首页 > 其它

Mybatis修改源码记录

2015-11-27 10:41 453 查看
需求:拦截系统所有删除sql,修改为假删除,即更新数据的删除状态

1.建立类PreparedStatementHandler,注意包路径与mybatis-3.2.3.jar一致

package org.apache.ibatis.executor.statement;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

public class PreparedStatementHandler extends BaseStatementHandler {

public PreparedStatementHandler(Executor executor,
MappedStatement mappedStatement, Object parameter,
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler,
boundSql);
}

public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps,
parameterObject);
return rows;
}

public void batch(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.addBatch();
}

public <E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.<E> handleResultSets(ps);
}

protected Statement instantiateStatement(Connection connection)
throws SQLException {
String sql = boundSql.getSql();
//删除语句替换为修改
sql = changeDeleteSql2UpdateSql(sql);

if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
String[] keyColumnNames = mappedStatement.getKeyColumns();
if (keyColumnNames == null) {
return connection.prepareStatement(sql,
PreparedStatement.RETURN_GENERATED_KEYS);
} else {
return connection.prepareStatement(sql, keyColumnNames);
}
} else if (mappedStatement.getResultSetType() != null) {
return connection.prepareStatement(sql, mappedStatement
.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
} else {
return connection.prepareStatement(sql);
}
}

public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}

/**
* 变化删除语句为更新语句
* @param originalSql 原始语句
* @return 变化后的语句
*/
private String changeDeleteSql2UpdateSql(String originalSql) {
Pattern patternDelete = Pattern.compile("\\bdelete\\b",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher matcherDelete = patternDelete.matcher(originalSql);
// 如果是删除语句
if (matcherDelete.find()) {
StringBuffer updateSql = new StringBuffer();
// 找到from关键字
Pattern patternFrom = Pattern.compile("\\bfrom\\b",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher matcherFrom = patternFrom.matcher(originalSql);
// 得到from关键字的结尾位置
if (matcherFrom.find()) {
int indexFromEnd = matcherFrom.end();
// 找到where的开头位置
Pattern patternWhere = Pattern.compile("\\bwhere\\b",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher matcherWhere = patternWhere.matcher(originalSql);

String tableName = "";
String whereSql = "";
// 如果找到where,where和from之间的都是表名
if (matcherWhere.find()) {
int indexWhereStart = matcherWhere.start();
tableName = originalSql.substring(indexFromEnd,
indexWhereStart);
whereSql = originalSql.substring(indexWhereStart);
}
// 如果没找到where,认为后面的都是表名
else {
tableName = originalSql.substring(indexFromEnd);
}
//如果表为工作流中的数据库表,则不做任何操作,直接返回。
if(tableName.toUpperCase().trim().startsWith("ACT_") || tableName.toUpperCase().trim().startsWith("PPP_")){
return  originalSql;
}
if (tableName != null && !tableName.trim().equals("")) {
updateSql.append("UPDATE ").append(tableName)
.append(" SET STATUS='2' ").append(whereSql);
}
if (updateSql != null && updateSql.length() > 1) {
originalSql = updateSql.toString();
}
}
}
return originalSql;
}

}


如此,项目移动后自定义的类会替换mybatis-3.2.3.jar中的对应类,即实现类的覆盖。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: