-
参考Mybatis-Plus方法生成策略(com.baomidou.mybatisplus.core.injector.methods.Update)
-
参考MySQL的INSERT INTO ON DUPLICATE KEY UPDATE语法
-
生成动态SQL脚本模板
CREATE TABLE `test_entity`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
定义实体
@Data
public class TestEntity {
@TableId
private Integer id;
private String name;
private Integer age;
}
定义Mapper接口
- 注意需要继承BaseMapper
public interface DuplicateKeyUpdateMapper动态SQL实现extends BaseMapper { int duplicateKeyUpdate(List list); }
public class DuplicateKeyUpdateMethod extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
//脚本模板
String sql = "";
//字段list(除了主键)
List fieldList = tableInfo.getFieldList();
//全部字段
List allFieldName = fieldList.stream()
.map(TableFieldInfo::getColumn)
.collect(Collectors.toList());
allFieldName.add(0, tableInfo.getKeyColumn());
//生成所需的sql片段
String fieldNames = String.join(", ", allFieldName);
String insertFields = allFieldName.stream()
.map(field -> "#{item." + field + "}")
.collect(Collectors.joining(", "));
insertFields = "(" + insertFields + ")";
String updateFields = fieldList.stream()
.map(field -> {
String column = field.getColumn();
return column + "=values(" + column + ")";
})
.collect(Collectors.joining(",n"));
//生成具体脚本
String sqlResult = String.format(sql, tableInfo.getTableName(), fieldNames, insertFields, updateFields);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
return this.addUpdateMappedStatement(mapperClass, modelClass, "duplicateKeyUpdate", sqlSource);
}
}
注入自定义Mapper
public class MyBatisPlusConfig {
@Bean
public DefaultSqlInjector myLogicSqlInjector() {
return new DefaultSqlInjector() {
@Override
public List getMethodList(Class> mapperClass) {
List methodList = super.getMethodList(mapperClass);
methodList.add(new DuplicateKeyUpdateMethod());
return methodList;
}
};
}
}



