【踩坑】mybatisplus saveOrUpdateBatch方法只有update不insert

背景

最近想做一个自用的记账本类似的项目,毕竟网上的软件谁知道把数据拿去做了啥呀,咱也不敢用啊,只有自己做一个了,引入了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;
    }
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中的代码是关于MyBatis Plus中的自动填充功能的使用。通过在实现MetaObjectHandler接口的类中重写insertFill和updateFill方法,可以在插入和更新数据时自动填充指定字段的值。在insertFill方法中,使用this.setFieldValByName方法将createTime字段的值设置为当前时间;在updateFill方法中,将updatedTime字段的值设置为当前时间。这样,在执行插入和更新操作时,相关字段会自动填充相应的值。 引用\[2\]中的代码是一个示例,展示了如何在实体类中使用@TableField注解来指定字段的填充策略。通过设置fill属性为FieldFill.INSERT或FieldFill.INSERT_UPDATE,可以指定在插入和插入更新操作时自动填充相应字段的值。 引用\[3\]中的代码是一个使用MyBatis Plus的lambda表达式进行更新操作的示例。在这个例子中,使用lambdaUpdate方法创建一个UpdateWrapper对象,并通过eq方法指定了更新条件,使用set方法设置了要更新的字段和值。最后,通过调用userMapper的update方法执行更新操作。 问题: mybatisplus insert_update是什么意思? 回答: mybatisplus中的insert_update是指在执行插入和更新操作时,同时进行插入和更新的操作。也就是说,当执行插入操作时,如果数据已存在,则会进行更新操作,如果数据不存在,则会进行插入操作。这样可以简化代码,提高操作的效率。 #### 引用[.reference_title] - *1* *2* [[简化开发] mybatis plus自动填充 INSERTINSERT_UPDATE (记录)](https://blog.csdn.net/pingzhuyan/article/details/126622969)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Mybatis-Plus中增(insert)删(delete)改(update)方法讲解-V1.0](https://blog.csdn.net/qq_53437402/article/details/126200627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值