소스 검색

处理冲突代码.

nieqiurong 1 년 전
부모
커밋
09b3aa7a54

+ 79 - 58
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/DataChangeRecorderInnerInterceptor.java

@@ -16,7 +16,6 @@
 package com.baomidou.mybatisplus.extension.plugins.inner;
 
 import java.io.Reader;
-import java.math.BigDecimal;
 import java.sql.Clob;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
@@ -25,7 +24,6 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -37,6 +35,7 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import net.sf.jsqlparser.statement.select.Values;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
@@ -75,13 +74,10 @@ import net.sf.jsqlparser.statement.select.AllColumns;
 import net.sf.jsqlparser.statement.select.FromItem;
 import net.sf.jsqlparser.statement.select.PlainSelect;
 import net.sf.jsqlparser.statement.select.Select;
-import net.sf.jsqlparser.statement.select.SelectBody;
-import net.sf.jsqlparser.statement.select.SelectExpressionItem;
 import net.sf.jsqlparser.statement.select.SelectItem;
 import net.sf.jsqlparser.statement.select.SetOperationList;
 import net.sf.jsqlparser.statement.update.Update;
 import net.sf.jsqlparser.statement.update.UpdateSet;
-import net.sf.jsqlparser.statement.values.ValuesStatement;
 
 /**
  * <p>
@@ -230,7 +226,8 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         selectBody.setSelectItems(buildColumns2SelectItems.getSelectItems());
         selectBody.setWhere(where);
         SelectItem<PlainSelect> plainSelectSelectItem = new SelectItem<>(selectBody);
-        BoundSql boundSql4Select = new BoundSql(mappedStatement.getConfiguration(),  plainSelectSelectItem.toString(),
+
+        BoundSql boundSql4Select = new BoundSql(mappedStatement.getConfiguration(), plainSelectSelectItem.toString(),
             prepareParameterMapping4Select(boundSql.getParameterMappings(), updateStmt),
             boundSql.getParameterObject());
         PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
@@ -240,12 +237,13 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
                 boundSql4Select.setAdditionalParameter(ety.getKey(), ety.getValue());
             }
         }
-        OriginalDataObj originalData = buildOriginalObjectData(selectBody, buildColumns2SelectItems.getPk(), mappedStatement, boundSql4Select, connection);
+        Map<String, Object> updatedColumnDatas = getUpdatedColumnDatas(table.getName(), boundSql, updateStmt);
+        OriginalDataObj originalData = buildOriginalObjectData(updatedColumnDatas, selectBody, buildColumns2SelectItems.getPk(), mappedStatement, boundSql4Select, connection);
         OperationResult result = new OperationResult();
         result.setOperation("update");
         result.setTableName(table.getName());
         result.setRecordStatus(true);
-        result.buildDataStr(compareAndGetUpdatedColumnDatas(result.getTableName(), boundSql, updateStmt, originalData));
+        result.buildDataStr(compareAndGetUpdatedColumnDatas(result.getTableName(), originalData, updatedColumnDatas));
         return result;
     }
 
@@ -279,13 +277,8 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         return originalMappingList.subList(removeParamCount, originalMappingList.size());
     }
 
-    /**
-     * @param updateSql
-     * @param originalDataObj
-     * @return
-     */
-    private List<DataChangedRecord> compareAndGetUpdatedColumnDatas(String tableName, BoundSql updateSql, Statement statement, OriginalDataObj originalDataObj) {
-        Map<String, String> columnNameValMap = new HashMap<>(updateSql.getParameterMappings().size());
+    protected Map<String, Object> getUpdatedColumnDatas(String tableName, BoundSql updateSql, Statement statement) {
+        Map<String, Object> columnNameValMap = new HashMap<>(updateSql.getParameterMappings().size());
         Map<Integer, String> columnSetIndexMap = new HashMap<>(updateSql.getParameterMappings().size());
         List<Column> selectItemsFromUpdateSql = new ArrayList<>();
         if (statement instanceof Update) {
@@ -293,7 +286,7 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
             int index = 0;
             for (UpdateSet updateSet : updateStmt.getUpdateSets()) {
                 selectItemsFromUpdateSql.addAll(updateSet.getColumns());
-                final List<Expression> updateList = updateSet.getExpressions();
+                final ExpressionList<Expression> updateList = (ExpressionList<Expression>) updateSet.getValues();
                 for (int i = 0; i < updateList.size(); ++i) {
                     Expression updateExps = updateList.get(i);
                     if (!(updateExps instanceof JdbcParameter)) {
@@ -326,12 +319,17 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
                 final String columnName = columnSetIndexMap.getOrDefault(index++, getColumnNameByProperty(propertyNameTrim, tableName));
                 if (relatedColumnsUpperCaseWithoutUnderline.containsKey(propertyNameTrim)) {
                     final String colkey = relatedColumnsUpperCaseWithoutUnderline.get(propertyNameTrim);
-                    final String val = String.valueOf(metaObject.getValue(propertyName));
+                    Object valObj = metaObject.getValue(propertyName);
+                    if (valObj instanceof IEnum) {
+                        valObj = ((IEnum<?>) valObj).getValue();
+                    } else if (valObj instanceof Enum) {
+                        valObj = getEnumValue((Enum) valObj);
+                    }
                     if (columnNameValMap.containsKey(colkey)) {
-                        columnNameValMap.put(relatedColumnsUpperCaseWithoutUnderline.get(propertyNameTrim), String.valueOf(columnNameValMap.get(colkey)).replace("?", val));
+                        columnNameValMap.put(relatedColumnsUpperCaseWithoutUnderline.get(propertyNameTrim), String.valueOf(columnNameValMap.get(colkey)).replace("?", valObj == null ? "" : valObj.toString()));
                     }
                     if (columnName != null && !columnNameValMap.containsKey(columnName)) {
-                        columnNameValMap.put(columnName, val);
+                        columnNameValMap.put(columnName, valObj);
                     }
                 } else {
                     if (columnName != null) {
@@ -343,12 +341,19 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
             }
         }
         dealWithUpdateWrapper(columnSetIndexMap, columnNameValMap, updateSql);
+        return columnNameValMap;
+    }
 
+    /**
+     * @param originalDataObj
+     * @return
+     */
+    private List<DataChangedRecord> compareAndGetUpdatedColumnDatas(String tableName, OriginalDataObj originalDataObj, Map<String, Object> columnNameValMap) {
         final Set<String> ignoredColumns = ignoredTableColumns.get(tableName.toUpperCase());
         if (originalDataObj == null || originalDataObj.isEmpty()) {
             DataChangedRecord oneRecord = new DataChangedRecord();
             List<DataColumnChangeResult> updateColumns = new ArrayList<>(columnNameValMap.size());
-            for (Map.Entry<String, String> ety : columnNameValMap.entrySet()) {
+            for (Map.Entry<String, Object> ety : columnNameValMap.entrySet()) {
                 String columnName = ety.getKey();
                 if ((ignoredColumns == null || !ignoredColumns.contains(columnName)) && !ignoreAllColumns.contains(columnName)) {
                     updateColumns.add(DataColumnChangeResult.constrcutByUpdateVal(columnName, ety.getValue()));
@@ -368,13 +373,25 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         return updateDataList;
     }
 
+    private Object getEnumValue(Enum enumVal) {
+        Optional<String> enumValueFieldName = MybatisEnumTypeHandler.findEnumValueFieldName(enumVal.getClass());
+        if (enumValueFieldName.isPresent()) {
+            return SystemMetaObject.forObject(enumVal).getValue(enumValueFieldName.get());
+        }
+        return enumVal;
+
+    }
+
     @SuppressWarnings("rawtypes")
-    private void dealWithUpdateWrapper(Map<Integer, String> columnSetIndexMap, Map<String, String> columnNameValMap, BoundSql updateSql){
+    private void dealWithUpdateWrapper(Map<Integer, String> columnSetIndexMap, Map<String, Object> columnNameValMap, BoundSql updateSql) {
         if (columnSetIndexMap.size() <= columnNameValMap.size()) {
             return;
         }
         MetaObject mpgenVal = SystemMetaObject.forObject(updateSql.getParameterObject());
-        Object ew = mpgenVal.getValue("ew");
+        if(!mpgenVal.hasGetter(Constants.WRAPPER)){
+            return;
+        }
+        Object ew = mpgenVal.getValue(Constants.WRAPPER);
         if (ew instanceof UpdateWrapper || ew instanceof LambdaUpdateWrapper) {
             final String sqlSet = ew instanceof UpdateWrapper ? ((UpdateWrapper) ew).getSqlSet() : ((LambdaUpdateWrapper) ew).getSqlSet();// columnName=#{val}
             if (sqlSet == null) {
@@ -408,32 +425,30 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         Map<String, String> columnNameValMap = new HashMap<>(4);
         final Select select = insert.getSelect();
         List<Column> columns = insert.getColumns();
-        if (select != null && select.getSelectBody() instanceof SetOperationList) {
-            SetOperationList setOperationList = (SetOperationList) select.getSelectBody();
-            final List<SelectBody> selects = setOperationList.getSelects();
+        if (select instanceof SetOperationList) {
+            SetOperationList setOperationList = (SetOperationList) select;
+            final List<Select> selects = setOperationList.getSelects();
             if (CollectionUtils.isEmpty(selects)) {
                 return columnNameValMap;
             }
-            final SelectBody selectBody = selects.get(0);
-            if (!(selectBody instanceof ValuesStatement)) {
+            final Select selectBody = selects.get(0);
+            if (!(selectBody instanceof Values)) {
                 return columnNameValMap;
             }
-            ValuesStatement valuesStatement = (ValuesStatement) selectBody;
+            Values valuesStatement = (Values) selectBody;
             if (valuesStatement.getExpressions() instanceof ExpressionList) {
-                ExpressionList expressionList = (ExpressionList) valuesStatement.getExpressions();
-                List<Expression> expressions = expressionList.getExpressions();
+                ExpressionList expressionList = valuesStatement.getExpressions();
+                List<Expression> expressions = expressionList;
                 for (Expression expression : expressions) {
                     if (expression instanceof RowConstructor) {
-                        final ExpressionList exprList = ((RowConstructor) expression).getExprList();
-                        if (exprList != null) {
-                            final List<Expression> insertExpList = exprList.getExpressions();
-                            for (int i = 0; i < insertExpList.size(); ++i) {
-                                Expression e = insertExpList.get(i);
-                                if (!(e instanceof JdbcParameter)) {
-                                    final String columnName = columns.get(i).getColumnName();
-                                    final String val = e.toString();
-                                    columnNameValMap.put(columnName, val);
-                                }
+                        final ExpressionList exprList = ((RowConstructor) expression);
+                        final List<Expression> insertExpList = exprList;
+                        for (int i = 0; i < insertExpList.size(); ++i) {
+                            Expression e = insertExpList.get(i);
+                            if (!(e instanceof JdbcParameter)) {
+                                final String columnName = columns.get(i).getColumnName();
+                                final String val = e.toString();
+                                columnNameValMap.put(columnName, val);
                             }
                         }
                     }
@@ -518,20 +533,21 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         }
     }
 
-    private OriginalDataObj buildOriginalObjectData(Select selectStmt, Column pk, MappedStatement mappedStatement, BoundSql boundSql, Connection connection) {
+    private OriginalDataObj buildOriginalObjectData(Map<String, Object> updatedColumnDatas, Select selectStmt, Column pk, MappedStatement mappedStatement, BoundSql boundSql, Connection connection) {
         try (PreparedStatement statement = connection.prepareStatement(selectStmt.toString())) {
             DefaultParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, boundSql.getParameterObject(), boundSql);
             parameterHandler.setParameters(statement);
             ResultSet resultSet = statement.executeQuery();
             List<DataChangedRecord> originalObjectDatas = new LinkedList<>();
             int count = 0;
+
             while (resultSet.next()) {
                 ++count;
                 if (checkTableBatchLimitExceeded(selectStmt, count)) {
                     logger.error("batch update limit exceed: count={}, BATCH_UPDATE_LIMIT={}", count, BATCH_UPDATE_LIMIT);
                     throw DataUpdateLimitationException.DEFAULT;
                 }
-                originalObjectDatas.add(prepareOriginalDataObj(resultSet, pk));
+                originalObjectDatas.add(prepareOriginalDataObj(updatedColumnDatas, resultSet, pk));
             }
             OriginalDataObj result = new OriginalDataObj();
             result.setOriginalDataObj(originalObjectDatas);
@@ -558,7 +574,7 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         if (!batchUpdateLimitationOpened) {
             return false;
         }
-        final PlainSelect selectBody = (PlainSelect) selectStmt.getSelectBody();
+        final PlainSelect selectBody = (PlainSelect) selectStmt;
         final FromItem fromItem = selectBody.getFromItem();
         if (fromItem instanceof Table) {
             Table fromTable = (Table) fromItem;
@@ -591,14 +607,20 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
      * @return
      * @throws SQLException
      */
-    private DataChangedRecord prepareOriginalDataObj(ResultSet resultSet, Column pk) throws SQLException {
+    private DataChangedRecord prepareOriginalDataObj(Map<String, Object> updatedColumnDatas, ResultSet resultSet, Column pk) throws SQLException {
         final ResultSetMetaData metaData = resultSet.getMetaData();
         int columnCount = metaData.getColumnCount();
         List<DataColumnChangeResult> originalColumnDatas = new LinkedList<>();
         DataColumnChangeResult pkval = null;
         for (int i = 1; i <= columnCount; ++i) {
             String columnName = metaData.getColumnName(i).toUpperCase();
-            DataColumnChangeResult col = DataColumnChangeResult.constrcutByOriginalVal(columnName, resultSet.getObject(i));
+            DataColumnChangeResult col;
+            Object updateVal = updatedColumnDatas.get(columnName);
+            if (updateVal != null && updateVal.getClass().getCanonicalName().startsWith("java.")) {
+                col = DataColumnChangeResult.constrcutByOriginalVal(columnName, resultSet.getObject(i, updateVal.getClass()));
+            } else {
+                col = DataColumnChangeResult.constrcutByOriginalVal(columnName, resultSet.getObject(i));
+            }
             if (pk != null && columnName.equalsIgnoreCase(pk.getColumnName())) {
                 pkval = col;
             } else {
@@ -614,24 +636,24 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
         return changedRecord;
     }
 
+
     private Columns2SelectItemsResult buildColumns2SelectItems(String tableName, List<Column> columns) {
         if (columns == null || columns.isEmpty()) {
-            return Columns2SelectItemsResult.build(Collections.singletonList(new AllColumns()), 0);
+            return Columns2SelectItemsResult.build(Collections.singletonList(new SelectItem<>(new AllColumns())), 0);
         }
-        List<SelectItem> selectItems = new ArrayList<>(columns.size());
+        List<SelectItem<?>> selectItems = new ArrayList<>(columns.size());
         for (Column column : columns) {
-            selectItems.add(new SelectExpressionItem(column));
+            selectItems.add(new SelectItem<>(column));
         }
-        for (TableInfo tableInfo : TableInfoHelper.getTableInfos()) {
-            if (tableName.equalsIgnoreCase(tableInfo.getTableName())) {
-                Column pk = new Column(tableInfo.getKeyColumn());
-                selectItems.add(new SelectItem<>(pk));
-                Columns2SelectItemsResult result = Columns2SelectItemsResult.build(selectItems, 1);
-                result.setPk(pk);
-                return result;
-            }
+        TableInfo tableInfo = getTableInfoByTableName(tableName);
+        if (tableInfo == null) {
+            return Columns2SelectItemsResult.build(selectItems, 0);
         }
-        return Columns2SelectItemsResult.build(selectItems, 0);
+        Column pk = new Column(tableInfo.getKeyColumn());
+        selectItems.add(new SelectItem<>(pk));
+        Columns2SelectItemsResult result = Columns2SelectItemsResult.build(selectItems, 1);
+        result.setPk(pk);
+        return result;
     }
 
     private String buildParameterObject(BoundSql boundSql) {
@@ -669,7 +691,6 @@ public class DataChangeRecorderInnerInterceptor implements InnerInterceptor {
     public OperationResult processDelete(Delete deleteStmt, MappedStatement mappedStatement, BoundSql boundSql, Connection connection) {
         Table table = deleteStmt.getTable();
         Expression where = deleteStmt.getWhere();
-        Select selectStmt = new Select();
         PlainSelect selectBody = new PlainSelect();
         selectBody.setFromItem(table);
         selectBody.setSelectItems(Collections.singletonList(new SelectItem<>((new AllColumns()))));