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("", tableInfo.getTableName(), columnScript, valuesScript, updateScript); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource, new NoKeyGenerator(), null, null); } }