mybatis-plus执行语句失效的一次解决思路

博主在Java监听事件中更新信息未成功。先排查是否因bean未加载,发现查询操作正常,排除该原因;又怀疑事务未提交,添加事务后更新仍失败。最后用p6spy打印sql,发现有两条更新语句,原来是监听结束后又用老数据更新,导致数据未变。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

话不多说,上代码

    @EventListener
    public void overEvent(OverTask overTask){
    log.info("查看数据="+overTask.getBusinessKey());
    Class aClass = getMap().get(overTask.getProcessName());;
        if(Objects.nonNull(aClass)){
            Long businessKeyId = Long.valueOf(overTask.getBusinessKey());
            IService service1 = (IService) SpringUtils.getBean(aClass);
            if(service1 instanceof GwfwFwlbService ){
                SpringUtils.getBean(GwfwFwlbService.class).
                update(Wrappers.lambdaUpdate(GwfwFwlb.class).
                set(GwfwFwlb::getStatus,FlowApprovalType.OVER).
                eq(GwfwFwlb::getId,businessKeyId));
            }
                    //。。。。。。。。。。。。
        }
        else {
            log.error("流程回调信息异常---->{}",overTask.toString());
        }
    }
}

        在一次监听事件当中,对某个信息进行了更新(set(GwfwFwlb::getStatus,FlowApprovalType.OVER)),但是结果却发现并没有更新成功。这个时候我就感到疑惑

        首先我是觉得,是不是bean没有加载进来,导致所有操作都不行,然后我打印日志,发现查询等操作是正常的,说明是bean加载了,并且并没有销毁掉。

        然后我就觉得,是不是事务没有提交的原因,然后我加上了事务(@Transactional(rollbackFor = Exception.class)),再次执行,发现更新操作依旧没有成功,这个时候我就很奇怪了,为什么只有更新操作没有成功呢,因为更新数据打印出来是更改了的,但是数据库显示数据依旧没有变化。

        没办法,只能使用大招了,添加p6spy看看sql

        此处省略N个字..............................

        打印sql时我发现,更新语句正常,但是有两个更新语句,这个时候我就很奇怪了,为什么有两个呢?然后想了想,这是监听事件,那肯定就是监听结束后,又执行了更新操作,那次更新操作的数据是监听更新前的老数据,所以导致了数据没有变化。

        但是实际上监听事件的更新操作是成功了的。只不过在监听后又把老数据进行更新,导致了某个数据没有发生变化。所以要吸取经验,不要犯跟我一样的错啊!!!!!!!!!

### MyBatis-Plus 批量更新失效的原因及解决方案 #### 1. 配置问题 MyBatis-Plus 的批量更新功能依赖于底层数据库的支持以及 Spring Boot 数据源的正确配置。如果未启用 `allowMultiQueries` 参数,则可能导致批量更新失败或抛出异常[^2]。这是因为某些数据库驱动默认情况下不允许执行多条 SQL 语句在一个请求中完成。 解决方法是在数据源 URL 中显式开启该选项,例如 MySQL 数据库可以这样设置: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true ``` #### 2. 插入/更新对象的数据校验 当调用 MyBatis-Plus 提供的批量更新方法(如 `updateBatchById` 或自定义实现)时,需确保传入的对象列表满足以下条件: - **字段非空验证**:对象中的主键字段不能为空,否则无法匹配到对应的记录进行更新。 - **字段映射一致性**:实体类属性名应与数据库列名保持一致,或者通过注解 `@TableField` 进行手动映射[^1]。 #### 3. 性能优化与分批处理 对于大规模数据集的操作,一次性提交可能引发性能瓶颈甚至超时错误。推荐采用分批方式来减少每次操作的影响范围。可以通过如下代码片段展示如何实现分批更新: ```java import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; @Service public class YourServiceImpl extends ServiceImpl<YourMapper, YourEntity> { public void batchUpdate(List<YourEntity> list) { int batchSize = 500; // 设置每批次大小 for (int i = 0; i < list.size(); i += batchSize) { int toIndex = Math.min(i + batchSize, list.size()); updateBatchById(list.subList(i, toIndex)); // 调用内置方法 } } } ``` 上述代码利用了 MyBatis-Plus 内建的 `updateBatchById` 方法,并将其分割成若干个小批次逐一提交给数据库处理[^3]。 #### 4. 自定义 SQL 注入器冲突 如果项目中有自定义 SQL 注入器但未正确注册或覆盖了框架原有的行为,可能会导致批量更新逻辑被忽略。此时需要检查是否遗漏了必要的 Bean 定义,比如下面的例子展示了如何声明一个兼容的标准注入器实例: ```java @Bean public MybatisSqlInjector sqlInjector() { return new DefaultSqlInjector(); } ``` 另外还需注意的是,在重写父类方法时要小心保留原有功能以免破坏预期的行为模式。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值