All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.changemonitor.parse.ParseUpdateData Maven / Gradle / Ivy

package com.github.changemonitor.parse;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.Select;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.RowBounds;

import com.github.changemonitor.domain.ChangeData;
import com.github.changemonitor.domain.ChangeDataUtil;
import com.github.changemonitor.enumerate.DBActionTypeEnum;
import com.github.changemonitor.filter.FilterContext;
import com.github.changemonitor.mybatis.MSUtils;
import com.github.changemonitor.mybatis.MybatisParameterUtils;
import com.github.changemonitor.sql.JsqlParserHelper;
import com.github.changemonitor.sql.SqlParserInfo;

public class ParseUpdateData implements ParseData {
	
	@Override
	public List parse(String commandName, MybatisInvocation mybatisInvocation) throws Throwable {
		List results = null;
		MappedStatement mappedStatement = mybatisInvocation.getMappedStatement();
		Object updateParameterObject = mybatisInvocation.getParameter();
		BoundSql boundSql = mappedStatement.getBoundSql(mybatisInvocation.getParameter());
		String sql = boundSql.getSql();
		
		SqlParserInfo sqlParserInfo = new SqlParserInfo(sql, DBActionTypeEnum.UPDATE);
		
		//校验过滤
		Boolean validateBoolean =  FilterContext.validate(sqlParserInfo.getTableName(), mybatisInvocation);
		if(!validateBoolean){
			return null;
		}
		
		//获取要更新数据
		ArrayList> queryResults = queryWillUpdateDatas(mybatisInvocation,boundSql, sqlParserInfo);
		
		//获取更新字段列表
		Map updateDataMap = MybatisParameterUtils.getParameter(mappedStatement, boundSql, updateParameterObject);
		//组装变更列表
		results =  buildChangeDatas(updateDataMap, queryResults,sqlParserInfo);
		return results;
	}
	
	private ArrayList> queryWillUpdateDatas(MybatisInvocation mybatisInvocation, 
			BoundSql boundSql, SqlParserInfo sqlParserInfo) throws SQLException{

		MappedStatement mappedStatement = mybatisInvocation.getMappedStatement();
		MappedStatement selectMappedStatement = MSUtils.newHashMapMappedStatement(mappedStatement);
		List updateColumns = new ArrayList<>();
		Column column = new Column();
		column.setColumnName("*");
		updateColumns.add(column);
		Expression whereExpression = sqlParserInfo.getWhereExpression();

		Select select = JsqlParserHelper.getSelect(sqlParserInfo.getTable(), updateColumns, whereExpression);
		String selectSqlString = select.toString();
		// 查询数量限制
		selectSqlString = mybatisInvocation.getDbDialect().getLimitSql(selectSqlString, mybatisInvocation.getMaxRowMonitor());
		
		List selectParamMap = new ArrayList<>();
		List whereIdList =JsqlParserHelper.getWhereColumn(whereExpression);
		for (ParameterMapping paramMap : boundSql.getParameterMappings()) {
			if(paramMap.getProperty()!=null &&
					whereIdList.contains(paramMap.getProperty().toLowerCase())){
				selectParamMap.add(paramMap);
				whereIdList.remove(paramMap.getProperty().toLowerCase());
			}
		}

		BoundSql queryBoundSql = new BoundSql(mybatisInvocation.getMappedStatement().getConfiguration(), selectSqlString, selectParamMap, mybatisInvocation.getParameter());
		Object queryResultList = mybatisInvocation.getExecutor().query(selectMappedStatement, mybatisInvocation.getParameter(), RowBounds.DEFAULT, null, null, queryBoundSql);
		@SuppressWarnings("unchecked")
		ArrayList> queryResults = (ArrayList>) queryResultList;
		return queryResults;
	}
	
	private List buildChangeDatas(final Map updateDataMap, 
			final ArrayList> queryResults,SqlParserInfo sqlParserInfo){
		List changeDatas = new ArrayList<>();
		if(queryResults != null && !queryResults.isEmpty()){
			for(HashMap queryDataMap : queryResults){
				ChangeData changeData = ChangeDataUtil.buildChangeDataForUpdate(updateDataMap,queryDataMap);
				changeData.setTableName(sqlParserInfo.getTableName());
				changeData.setSchemaName(sqlParserInfo.getSchemaName());
				changeData.setEventType(DBActionTypeEnum.UPDATE.getKey());
				changeDatas.add(changeData);
			}
		}
		return changeDatas;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy