Mybatis修改源码记录

需求:拦截系统所有删除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中的对应类,即实现类的覆盖。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值