c语言编程笔录

首页 >   > 笔记大全

笔记大全

mybatisplus批量更新太慢该怎么解决

更新时间:2023-12-21

问题描述

mybatisplus批量更新的效率较慢,需要寻找解决方案提升效率。具体表现是更新一批数据耗费的时间过长,操作记录多达数万条,执行时间可能长达几十秒。这也会造成长时间的数据库锁定,使得其他操作不能对数据库进行读写。

解决方案一:使用批量更新的方式

mybatisplus默认会对每一条数据进行一次数据库连接和一次SQL执行,这种方式的效率较低,会使得批量数据更新变得缓慢。可以使用mybatis batch批量更新方式来提高效率。批量更新是指将多个SQL语句一次性提交到数据库执行,减少连接时间和SQL语句执行时间。

  public class MybatisPlusBatchUpdateMapper {
      /**
       * 批量更新实现
       * @return 更新行数
       */
      public int batchUpdate() {
          List list = getDataList();
          int count = 0;
          // 设置sqlSession批量操作
          SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);
          try {
              MybatisPlusMapper mapper = sqlSession.getMapper(MybatisPlusMapper.class);
              for (DataEntity entity : list) {
                  // 执行更新操作
                  mapper.updateById(entity);
                  count++;
              }
              // 执行批量更新操作
              sqlSession.flushStatements();
              sqlSession.commit();
          } finally {
              sqlSession.close();
          }
          return count;
      }
  }

解决方案二:使用MyBatisPlus 3.3以上的版本

从MyBatisPlus 3.3版本开始,官方对批量更新进行了优化,提供了批量更新的相关API。该API利用了JDBC的批处理,将多条SQL语句发送到数据库一次性执行,减少了很多连接时间和SQL语句执行时间。同时,MyBatisPlus也为批量更新提供了注解和更新器来简化操作。

 @Mapper
 public interface UserMapper extends MyBaseMapper {
     @UpdateBatch(chunkSize = 1000)
     int batchUpdate1(List list);
     
     int batchUpdate2(List list);
 }

解决方案三:使用缓存机制

mybatisplus默认会使用二级缓存来优化查询效率,但是对于更新操作,不提供二级缓存的支持。但是我们可以采用调整一级缓存的方式来优化更新操作。 一级缓存是指SQLSession级别的缓存,也就是说,在一个事务环境中,多个操作共用一个SQLSession的情况下,一级缓存可以减少SQL语句的重复执行次数。

  public class MybatisPlusCacheMapper {
      /**
       * 增加缓存实现
       * @return 更新行数
       */
      public int updateWithCache() {
          List list = getDataList();
          int count = 0;
          // 查询操作使用缓存
          SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession();
          try {
              MybatisPlusMapper mapper = sqlSession.getMapper(MybatisPlusMapper.class);
              for (DataEntity entity : list) {
                  // 查询结果将会放入一级缓存
                  mapper.selectById(entity.getId());
                  // 执行更新操作
                  mapper.updateById(entity);
                  count++;
              }
              // 手动清理缓存,防止缓存溢出
              sqlSession.clearCache();
              sqlSession.commit();
          } finally {
              sqlSession.close();
          }
          return count;
      }
  }

总结

mybatisplus的批量更新操作在数据量过大时,效率会比较低,可能会引起长时间的数据库锁定。我们可以通过使用批量更新的方式,MyBatisPlus 3.3以上的版本或者调整缓存机制来解决这个问题。通过技术层面的优化,我们可以提高更新效率,减少数据库的锁定时间,保障数据库的高可用性。