解决MybatisPlus使⽤insertBatchSomeColumn批量插⼊Null字。。。⼀、场景
1. Mybatis Plus默认提供了insertBatchSomeColumn选装件
2. 当批量插⼊的PO对象是NULL值,且数据库字段是NotNull且有默认值时就会报Value Not Null异常
⼆、解决思路
1. 在代码⽣成器时对PO对象赋予默认值
2. 在BaseServiceImpl实现类中对PO对象值为Null,数据库字段NotNull且有默认的值字段⾃动设置默认值
三、实现
3.1 代码⽣成器解决⽅法
1. 重写AutoGenerator
/*
package com.fig;
import batisplus.annotation.TableId;
import batisplus.annotation.TableLogic;
import batisplus.annotation.TableName;
import batisplus.annotation.Version;
import lkit.CollectionUtils;
import lkit.StringUtils;
import sion.activerecord.Model;
import ator.InjectionConfig;
import fig.*;
import fig.builder.ConfigBuilder;
import fig.po.TableField;
import fig.po.TableInfo;
import fig.rules.DbColumnType;
import ine.AbstractTemplateEngine;
import ine.VelocityTemplateEngine;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
perimental.Accessors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* ⽣成⽂件
*
* @author YangHu, tangguo, hubin
* @since 2016-08-30
*/
@Data
@Accessors(chain =true)
public class AutoGeneratorHelper {
private static final Logger logger = Logger(AutoGeneratorHelper.class);
/**
* 配置信息
*/
protected ConfigBuilder config;
/**
* 注⼊配置
*/
*/
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
protected InjectionConfig injectionConfig;
/**
* 数据源配置
*/
private DataSourceConfig dataSource;
/**
* 数据库表配置
*/
private StrategyConfig strategy;
/**
* 包相关配置
*/
private PackageConfig packageInfo;
/**
* 模板相关配置
*/
private TemplateConfig template;
/**
* 全局相关配置
*/
private GlobalConfig globalConfig;
/**
* 模板引擎
*/
private AbstractTemplateEngine templateEngine;
/**
* ⽣成代码
*/
public void execute(){
logger.debug("==========================准备⽣成⽂件...==========================");
/
/ 初始化配置
if(null == config){
config =new ConfigBuilder(packageInfo, dataSource, strategy, template, globalConfig);
if(null != injectionConfig){
injectionConfig.setConfig(config);
}
}
processTableFieldDefaultValue();
if(null == templateEngine){
// 为了兼容之前逻辑,采⽤ Velocity 引擎【默认】
templateEngine =new VelocityTemplateEngine();
}
// 模板引擎初始化执⾏⽂件输出
templateEngine.init(this.pretreatmentConfigBuilder(config)).mkdirs().batchOutput().open();
logger.debug("==========================⽂件⽣成完成=========================="); }
private void processTableFieldDefaultValue(){
for(TableInfo tableInfo : TableInfoList()){
for(TableField field : Fields()){
Map<String, Object> customMap = CustomMap();
DbColumnType columnType =(DbColumnType) ColumnType();
String defaultValue =(String) ("Default");
if(Objects.isNull(defaultValue)){
continue;
}
Object val = null;
switch(columnType){
case BYTE:
case SHORT:
case SHORT:
case CHARACTER:
case INTEGER:
val = defaultValue;
break;
case LONG:
val = defaultValue +"L";
break;
case FLOAT:
val = defaultValue +"F";
break;
case DOUBLE:
val = defaultValue +"D";
break;
case BOOLEAN:
val ="Boolean.valueOf(\""+ defaultValue +"\")";
break;
case STRING:
val ="\""+ defaultValue +"\"";
break;
case LOCAL_DATE:
if("CURRENT_TIMESTAMP".equals(defaultValue)){
val ="w()";
break;
}
val ="LocalDateTime.parse(\""+ defaultValue +"\", DateTimeFormatter.ofPattern("yyyy-MM-dd")).toLocalDate()";
break;
case LOCAL_TIME:
if("CURRENT_TIMESTAMP".equals(defaultValue)){
val ="w()";
break;
}
val ="LocalDateTime.parse(\""+ defaultValue +"\", DateTimeFormatter.ofPattern("HH:mm:ss")).toLocalTime()";
break;
case LOCAL_DATE_TIME:
if("CURRENT_TIMESTAMP".equals(defaultValue)){
val ="w()";
break;
}
val ="LocalDateTime.parse(\""+ defaultValue +"\", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))";
break;
case DATE:
val ="new Date()";
break;
case BIG_INTEGER:
val ="new BigInteger(\""+ defaultValue +"\")";
break;
case BIG_DECIMAL:
val ="new BigDecimal(\""+ defaultValue +"\")";
break;
}
customMap.put("Default", val);
customMap.put("DefaultValueFieldName","DEFAULT_"+ CaseFormat.(CaseFormat.UPPER_UNDERSCORE, Prope rtyName()));
}
}
}
/**
* 开放表信息、预留⼦类重写
*
* @param config 配置信息
* @return ignore
*/
protected List<TableInfo>getAllTableInfoList(ConfigBuilder config){
protected List<TableInfo>getAllTableInfoList(ConfigBuilder config){
TableInfoList();
}
/**
* 预处理配置
*
* @param config 总配置信息
* @return 解析数据结果集
*/
protected ConfigBuilder pretreatmentConfigBuilder(ConfigBuilder config){
/*
* 注⼊⾃定义配置
*/
if(null != injectionConfig){
injectionConfig.initMap();
config.setInjectionConfig(injectionConfig);
}
/*
* 表信息列表
*/
List<TableInfo> tableList =AllTableInfoList(config);
for(TableInfo tableInfo : tableList){
/* ---------- 添加导⼊包 ---------- */
GlobalConfig().isActiveRecord()){
// 开启 ActiveRecord 模式
tableInfo.setImportPackages(CanonicalName());
}
if(tableInfo.isConvert()){
// 表注解
tableInfo.setImportPackages(CanonicalName());
}
StrategyConfig().getLogicDeleteFieldName()!= null && tableInfo.StrategyConfig().getLogicDeleteFieldName())) {
// 逻辑删除注解
tableInfo.setImportPackages(CanonicalName());
}
if(StringUtils.StrategyConfig().getVersionFieldName())){
// 乐观锁注解datasource是什么意思
tableInfo.setImportPackages(CanonicalName());
}
boolean importSerializable =true;
if(StringUtils.SuperEntityClass())){
// ⽗实体
tableInfo.SuperEntityClass());
importSerializable =false;
}
GlobalConfig().isActiveRecord()){
importSerializable =true;
}
if(importSerializable){
tableInfo.setImportPackages(CanonicalName());
}
// Boolean类型is前缀处理
StrategyConfig().isEntityBooleanColumnRemoveIsPrefix()
&& CollectionUtils.Fields())){
List<TableField> tableFields = Fields().stream().filter(field ->"boolean".PropertyType())) .filter(field -> PropertyName().startsWith("is")).List());
tableFields.forEach(field ->{
//主键为is的情况基本上是不存在的.
if(field.isKeyFlag()){
tableInfo.setImportPackages(CanonicalName());
}else{
tableInfo.setImportPackages(batisplus.annotation.CanonicalName());
}
field.setConvert(true);
field.PropertyName(),2));
field.PropertyName(),2));
});
}
}
return config.setTableInfoList(tableList);
}
public InjectionConfig getCfg(){
return injectionConfig;
}
public AutoGeneratorHelper setCfg(InjectionConfig injectionConfig){
this.injectionConfig = injectionConfig;
return this;
}
}
2. 修改配置
AutoGeneratorHelper autoGenerator =new AutoGeneratorHelper();
//...
DataSourceConfig dataSourceConfig =getDataSourceConfig(generateDTO);
dataSourceConfig.setDbQuery(new MySqlQuery(){
@Override
public String[]fieldCustom(){
return new String[]{"Default"};
}
});
//...
autoGenerator.setDataSource(dataSourceConfig);
3. 编写Entity模板
#if(${field.customMap.Default})
#if(!${field.fill})
@TableField(fill = FieldFill.INSERT)
#end
private ${field.propertyType} ${field.propertyName};
public static final ${field.propertyType} ${field.customMap.DefaultValueFieldName} = ${field.customMap.Default}; #end
#if(!${field.customMap.Default})
private ${field.propertyType} ${field.propertyName};
#end
4. DAO层
public interface CommonMapper<T>extends BaseMapper<T>{
int insertBatchSomeColumn(List<T> entityList);
}
5. BaseServiceImpl对Null值处理
public class CommonServiceImpl<M extends CommonMapper<T>, T>extends ServiceImpl<M, T>{
private static ConcurrentMap<String, List<Field>> defaultValueFields =new ConcurrentHashMap<>(); private static ConcurrentMap<Field, Object> defaultFieldValue =new ConcurrentHashMap<>();
private static final int BATCH_SIZE =1000;
private static final String DEFAULT_VALUE_PREFIX ="DEFAULT_";
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论