背景
最近想做一个自用的记账本类似的项目,毕竟网上的软件谁知道把数据拿去做了啥呀,咱也不敢用啊,只有自己做一个了,引入了mybatisplus,在用saveOrUpdateBatch的时候出现了点小问题,因为账单这里我是用微信和支付宝订单id来做主键的,在插入的时候就把值set进了实体类,结果数据一直写不进去,看了下日志,全都是update语句,纳尼?????这不是updateorinert吗,并且我表里面一条数据也没有呀,这是怎么回事呢,先百度了下,没有搜到答案,可能是姿势不对吧,算了,还是自己看源码吧,终于发现问题在哪里了,以下根据源码做分析
源码
以下是com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveOrUpdateBatch(java.util.Collection<T>, int)
的源码
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
if (CollectionUtils.isEmpty(entityList)) {
throw new IllegalArgumentException("Error: entityList must not be empty");
}
Class<?> cls = null;
TableInfo tableInfo = null;
int i = 0;
try (SqlSession batchSqlSession = sqlSessionBatch()) {
for (T anEntityList : entityList) {
if (i == 0) {
cls = anEntityList.getClass();
tableInfo = TableInfoHelper.getTableInfo(cls);
}
if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
// 这里通过实体类的@TableId注解获取主键的值
Object idVal = ReflectionKit.getMethodValue(cls, anEntityList, tableInfo.getKeyProperty());
// 因为我这里的主键是订单id,从微信和支付宝获取的,所以肯定是有值的,这里的校验不通过,所以insert一直没进去
if (StringUtils.checkValNull(idVal)) {
String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
batchSqlSession.insert(sqlStatement, anEntityList);
} else {
String sqlStatement = sqlStatement(SqlMethod.UPDATE_BY_ID);
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, anEntityList);
batchSqlSession.update(sqlStatement, param);
}
if (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
i++;
} else {
throw ExceptionUtils.mpe("Error: Can not execute. Could not find @TableId.");
}
batchSqlSession.flushStatements();
}
}
return true;
}
解决方法
本来是想自己写个sql的,但是不想动(懒是原罪),于是重写了saveOrUpdateBatch方法,先将就用着吧。
@Service
public class BillDetailServiceImpl extends ServiceImpl<BillDetailMapper, BillDetail> implements BillDetailService {
@Override
public boolean saveOrUpdateBatch(Collection<BillDetail> entityList,int batchSize) {
if (CollectionUtils.isEmpty(entityList)) {
throw new IllegalArgumentException("Error: entityList must not be empty");
}
Class<?> cls = null;
TableInfo tableInfo = null;
int i = 0;
try (SqlSession batchSqlSession = sqlSessionBatch()) {
for (BillDetail billDetail : entityList) {
if (i == 0) {
cls = billDetail.getClass();
tableInfo = TableInfoHelper.getTableInfo(cls);
}
if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
BillDetail bill = this.getById(billDetail.getOrderId());
if (bill == null) {
String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
batchSqlSession.insert(sqlStatement, billDetail);
} else {
String sqlStatement = sqlStatement(SqlMethod.UPDATE_BY_ID);
MapperMethod.ParamMap<BillDetail> param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, billDetail);
batchSqlSession.update(sqlStatement, param);
}
if (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
i++;
} else {
throw ExceptionUtils.mpe("Error: Can not execute. Could not find @TableId.");
}
batchSqlSession.flushStatements();
}
}
return true;
}
}