You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
2.7 KiB
56 lines
2.7 KiB
|
1 month ago
|
package com.project.base.config;
|
||
|
|
|
||
|
|
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||
|
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||
|
|
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||
|
|
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
|
||
|
|
import org.apache.ibatis.mapping.MappedStatement;
|
||
|
|
import org.apache.ibatis.mapping.SqlSource;
|
||
|
|
|
||
|
|
import java.util.stream.Collectors;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 自定义选装件:MySQL 批量 Upsert
|
||
|
|
*/
|
||
|
|
public class InsertBatchOnDuplicateKeyUpdate extends AbstractMethod {
|
||
|
|
|
||
|
|
protected InsertBatchOnDuplicateKeyUpdate() {
|
||
|
|
super("batchUpsert"); // 方法名
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||
|
|
final String methodName = "batchUpsert";
|
||
|
|
|
||
|
|
// 1. 准备 INSERT 字段
|
||
|
|
String columnScript = "(" + tableInfo.getKeyColumn() + "," +
|
||
|
|
tableInfo.getFieldList().stream()
|
||
|
|
.map(TableFieldInfo::getColumn)
|
||
|
|
.collect(Collectors.joining(",")) + ")";
|
||
|
|
|
||
|
|
// 2. 准备 VALUES 部分 (修复重点!)
|
||
|
|
String valuesScript = "(#{item." + tableInfo.getKeyProperty() + "}," +
|
||
|
|
tableInfo.getFieldList().stream()
|
||
|
|
.map(i -> {
|
||
|
|
// 【核心修复】检查该字段是否有 TypeHandler (如 JacksonTypeHandler)
|
||
|
|
if (i.getTypeHandler() != null) {
|
||
|
|
// 生成格式如:#{item.depIdPath,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler}
|
||
|
|
return "#{item." + i.getProperty() + ",typeHandler=" + i.getTypeHandler().getName() + "}";
|
||
|
|
}
|
||
|
|
return "#{item." + i.getProperty() + "}";
|
||
|
|
})
|
||
|
|
.collect(Collectors.joining(",")) + ")";
|
||
|
|
|
||
|
|
// 3. 准备 ON DUPLICATE KEY UPDATE 部分
|
||
|
|
String updateScript = tableInfo.getFieldList().stream()
|
||
|
|
.filter(i -> !i.getColumn().equals("create_time"))
|
||
|
|
.map(i -> i.getColumn() + " = VALUES(" + i.getColumn() + ")")
|
||
|
|
.collect(Collectors.joining(",")) + ", update_time = NOW()";
|
||
|
|
|
||
|
|
String sql = String.format("<script>INSERT INTO %s %s VALUES <foreach collection=\"list\" item=\"item\" separator=\",\">%s</foreach> ON DUPLICATE KEY UPDATE %s</script>",
|
||
|
|
tableInfo.getTableName(), columnScript, valuesScript, updateScript);
|
||
|
|
|
||
|
|
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
|
||
|
|
return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource, new NoKeyGenerator(), null, null);
|
||
|
|
}
|
||
|
|
}
|