Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/3.0' into 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
qmdx committed Apr 2, 2024
2 parents 95a196f + 7eee3d4 commit f83af0b
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,13 +24,13 @@
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;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -51,6 +50,7 @@
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
Expand Down Expand Up @@ -199,7 +199,8 @@ public OperationResult processInsert(Insert insertStmt, BoundSql boundSql) {
result.setOperation("insert");
result.setTableName(insertStmt.getTable().getName());
result.setRecordStatus(true);
result.buildDataStr(compareAndGetUpdatedColumnDatas(result.getTableName(), boundSql, insertStmt, null));
Map<String, Object> updatedColumnDatas = getUpdatedColumnDatas(result.getTableName(), boundSql, insertStmt);
result.buildDataStr(compareAndGetUpdatedColumnDatas(result.getTableName(), null, updatedColumnDatas));
return result;
}

Expand Down Expand Up @@ -238,15 +239,25 @@ public OperationResult processUpdate(Update updateStmt, MappedStatement mappedSt
boundSql4Select.setAdditionalParameter(ety.getKey(), ety.getValue());
}
}
OriginalDataObj originalData = buildOriginalObjectData(selectStmt, buildColumns2SelectItems.getPk(), mappedStatement, boundSql4Select, connection);
Map<String, Object> updatedColumnDatas = getUpdatedColumnDatas(table.getName(), boundSql, updateStmt);
OriginalDataObj originalData = buildOriginalObjectData(updatedColumnDatas, selectStmt, 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;
}

private TableInfo getTableInfoByTableName(String tableName) {
for (TableInfo tableInfo : TableInfoHelper.getTableInfos()) {
if (tableName.equalsIgnoreCase(tableInfo.getTableName())) {
return tableInfo;
}
}
return null;
}

/**
* 将update SET部分的jdbc参数去除
*
Expand All @@ -268,13 +279,8 @@ private List<ParameterMapping> prepareParameterMapping4Select(List<ParameterMapp
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) {
Expand Down Expand Up @@ -315,12 +321,17 @@ private List<DataChangedRecord> compareAndGetUpdatedColumnDatas(String tableName
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) {
Expand All @@ -332,12 +343,19 @@ private List<DataChangedRecord> compareAndGetUpdatedColumnDatas(String tableName
}
}
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()));
Expand All @@ -357,8 +375,17 @@ private List<DataChangedRecord> compareAndGetUpdatedColumnDatas(String tableName
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;
}
Expand Down Expand Up @@ -507,20 +534,21 @@ private String buildOriginalData(Select selectStmt, MappedStatement mappedStatem
}
}

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);
Expand Down Expand Up @@ -580,14 +608,20 @@ private boolean checkTableBatchLimitExceeded(Select selectStmt, int count) {
* @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 {
Expand All @@ -603,6 +637,7 @@ private DataChangedRecord prepareOriginalDataObj(ResultSet resultSet, Column pk)
return changedRecord;
}


private Columns2SelectItemsResult buildColumns2SelectItems(String tableName, List<Column> columns) {
if (columns == null || columns.isEmpty()) {
return Columns2SelectItemsResult.build(Collections.singletonList(new AllColumns()), 0);
Expand All @@ -611,16 +646,15 @@ private Columns2SelectItemsResult buildColumns2SelectItems(String tableName, Lis
for (Column column : columns) {
selectItems.add(new SelectExpressionItem(column));
}
for (TableInfo tableInfo : TableInfoHelper.getTableInfos()) {
if (tableName.equalsIgnoreCase(tableInfo.getTableName())) {
Column pk = new Column(tableInfo.getKeyColumn());
selectItems.add(new SelectExpressionItem(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 SelectExpressionItem(pk));
Columns2SelectItemsResult result = Columns2SelectItemsResult.build(selectItems, 1);
result.setPk(pk);
return result;
}

private String buildParameterObject(BoundSql boundSql) {
Expand Down Expand Up @@ -815,28 +849,22 @@ public static class DataColumnChangeResult {
@SuppressWarnings("rawtypes")
public boolean isDataChanged(Object updateValue) {
if (!Objects.equals(originalValue, updateValue)) {
if (updateValue instanceof Number && originalValue instanceof Number) {
BigDecimal update = new BigDecimal(updateValue.toString());
BigDecimal original = new BigDecimal(originalValue.toString());
return update.compareTo(original) != 0;
}
if (updateValue instanceof Date && originalValue instanceof Date) {
Date update = (Date) updateValue;
Date original = (Date) originalValue;
return update.compareTo(original) != 0;
}
if (originalValue instanceof Clob) {
String originalStr = convertClob((Clob) originalValue);
setOriginalValue(originalStr);
return !originalStr.equals(updateValue);
}
if (originalValue instanceof Comparable) {
Comparable original = (Comparable) originalValue;
Comparable update = (Comparable) updateValue;
try {
return update == null || original.compareTo(update) != 0;
} catch (Exception e) {
return true;
}
}
return true;
}
if (originalValue instanceof Comparable) {
Comparable original = (Comparable) originalValue;
Comparable update = (Comparable) updateValue;
return original.compareTo(update) != 0;
}
return false;
}

Expand Down Expand Up @@ -895,7 +923,7 @@ public static class DataChangedRecord {
private List<DataColumnChangeResult> originalColumnDatas;
private List<DataColumnChangeResult> updatedColumns;

public boolean hasUpdate(Map<String, String> columnNameValMap, Set<String> ignoredColumns, Set<String> ignoreAllColumns) {
public boolean hasUpdate(Map<String, Object> columnNameValMap, Set<String> ignoredColumns, Set<String> ignoreAllColumns) {
if (originalColumnDatas == null) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -204,21 +205,29 @@ void testUpdateByIdWithOptLock() {
user.setDesc("asdf");
user.setTestType(1);
user.setVersion(1);
final LocalDateTime dateTime = LocalDateTime.of(2024, 3, 29, 10, 0, 0);
user.setCreatedDt(dateTime);
userService.save(user);

H2User userDB = userService.getById(id);
Assertions.assertEquals(1, userDB.getVersion().intValue());
Assertions.assertTrue(userDB.getCreatedDt().compareTo(dateTime) == 0);

userDB.setName("992");
userDB.setCreatedDt(dateTime);
System.out.println("===============================================");
userService.updateById(userDB);
Assertions.assertEquals(2, userDB.getVersion().intValue(), "updated version value should be updated to entity");

userDB = userService.getById(id);
Assertions.assertEquals(2, userDB.getVersion().intValue());
Assertions.assertEquals("992", userDB.getName());
userService.lambdaUpdate().set(H2User::getAge,AgeEnum.THREE).eq(H2User::getTestId,id).update();
userDB.setCreatedDt(LocalDateTime.now());
userService.updateById(userDB);
System.out.println("===============================================");
userService.lambdaUpdate().set(H2User::getAge, AgeEnum.THREE).eq(H2User::getTestId, id).update();
UpdateWrapper<H2User> wp = new UpdateWrapper<>();
wp.set("age",AgeEnum.TWO).eq("test_id",id);
wp.set("age", AgeEnum.TWO);
wp.set("name", "yanjinyin@gitee");
userService.update(wp);

Expand Down Expand Up @@ -507,12 +516,10 @@ void notParser() throws Exception {
final Select select = (Select) CCJSqlParserUtil.parse(targetSql1);
Assertions.assertEquals(select.toString(), targetSql1);


final String targetSql2 = "SELECT * FROM user WHERE id NOT IN (?)";
final Select select2 = (Select) CCJSqlParserUtil.parse(targetSql2);
Assertions.assertEquals(select2.toString(), targetSql2);


final String targetSql3 = "SELECT * FROM user WHERE id IS NOT NULL";
final Select select3 = (Select) CCJSqlParserUtil.parse(targetSql3);
Assertions.assertEquals(select3.toString(), targetSql3);
Expand Down Expand Up @@ -868,16 +875,19 @@ protected LambdaQueryChainWrapper<H2User> doOrderByDesc(boolean condition, SFunc
System.out.println("-------处理OrderByDesc----------");
return super.doOrderByDesc(condition, column, columns);
}

@Override
protected LambdaQueryChainWrapper<H2User> doOrderByAsc(boolean condition, SFunction<H2User, ?> column, List<SFunction<H2User, ?>> columns) {
protected LambdaQueryChainWrapper<H2User> doOrderByAsc(boolean condition, SFunction<H2User, ?> column, List<SFunction<H2User, ?>> columns) {
System.out.println("-------处理OrderByAsc----------");
return super.doOrderByAsc(condition, column, columns);
}

@Override
protected LambdaQueryChainWrapper<H2User> doOrderBy(boolean condition, boolean isAsc, SFunction<H2User, ?> column, List<SFunction<H2User, ?>> columns) {
System.out.println("-------处理OrderBy----------");
return super.doOrderBy(condition, isAsc, column, columns);
}

@Override
protected LambdaQueryChainWrapper<H2User> doGroupBy(boolean condition, SFunction<H2User, ?> column, List<SFunction<H2User, ?>> columns) {
System.out.println("-------处理GroupBy----------");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@
*/
package com.baomidou.mybatisplus.test.h2.entity;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.test.h2.enums.AgeEnum;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.math.BigDecimal;
import java.util.Date;

/**
* 测试用户类
*
Expand Down Expand Up @@ -75,6 +77,9 @@ public class H2User extends SuperEntity {
@TableLogic
private Integer deleted;

@TableField("created_dt")
private LocalDateTime createdDt;


public H2User() {

Expand Down
1 change: 1 addition & 0 deletions mybatis-plus/src/test/resources/h2/user.ddl.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CREATE TABLE IF NOT EXISTS h2user (
price DECIMAL(10,2) NULL DEFAULT NULL,
desc VARCHAR(30) NULL DEFAULT NULL ,
version INT(5) NULL DEFAULT NULL,
created_dt TIMESTAMP NULL,
last_updated_dt TIMESTAMP NULL,
deleted INT(1) NULL DEFAULT 0 ,
PRIMARY KEY (test_id)
Expand Down

0 comments on commit f83af0b

Please sign in to comment.