MyBatis-Plus 学习笔记-流式查询

        在使用 MyBatis-Plus 进行流式查询时,通常是为了处理大量数据而避免一次性加载所有数据到内存中,从而减少内存消耗并提高性能。

        MyBatis-Plus 从 3.5.4 版本开始支持流式查询,这是 MyBatis 的原生功能,通过 ResultHandler 接口实现结果集的流式查询。这种查询方式适用于数据跑批或处理大数据的业务场景。

        在 BaseMapper 中,新增了多个重载方法,包括 selectList, selectByMap, selectBatchIds, selectMaps, selectObjs,这些方法可以与流式查询结合使用。

        需要注意的是,在低版本的 MyBatis-Plus 中,如果自定义 ResultHandler 结合分页查询,可能会出现错误。在这种情况下,需要手动关闭 count 查询。

使用示例

批量数据录入

刚好顺便学习下mybatisplus 批量数据录入

数据准备  10万条数据

@Autowired
	private MybatisUserService mybatisUserService;

	@Test
	void contextLoads() {
		List<MybatisUser> mybatisUsers = new ArrayList<>();
		for (int i = 0; i < 100000; i++) {
			MybatisUser mybatisUser = new MybatisUser();
			mybatisUser.setId(i);
			mybatisUser.setName("A"+i);
			mybatisUser.setSex(SexEnum.MAN);
			mybatisUsers.add(mybatisUser);
		}
		mybatisUserService.insertBatch(mybatisUsers);
	}

MybatisBatch方式

 // 记录开始时间,用于计算执行耗时
        long startTime = System.nanoTime(); // 使用 nanoTime 获取更精确的时间

        // 创建 MybatisBatch 对象,用于执行批量操作
        MybatisBatch<MybatisUser> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, mybatisUser);
        // 创建 MybatisBatch.Method 对象,指定具体的操作方法
        MybatisBatch.Method<MybatisUser> method = new MybatisBatch.Method<>(MybatisUserDao.class);
        // 执行插入操作
        mybatisBatch.execute(method.insert());

        // 记录结束时间,用于计算执行耗时
        long endTime = System.nanoTime(); // 获取结束时间

        // 计算执行时间并打印
        long executionTime = endTime - startTime;
        System.out.println("Execution time: " + executionTime + " nanoseconds");

SQL values方式

    @Insert("<script>" +
            "INSERT INTO `mybatis_user`(`id`, `name`, `sex`) " +
            "VALUES " +
            "<foreach collection= 'list' item= 'item' separator= ','> " +
            "(#{item.id},#{item.name},#{item.sex})" +
            "</foreach></script>")
    int insertBatchSql(@Param("list") List<MybatisUser> list);

 虽然插入很快,但是不是特别推荐,当实体数据过多的时候,sql拼接可能会出问题。

推荐的话 还是用多线程来分批插入。

流式查询

/**
     * 选择并处理数据库中的所有用户记录
     * 此方法使用baseMapper从数据库中选择所有用户记录,并使用ResultHandler进行处理
     * 每处理一条记录,都会在控制台输出当前记录的信息
     */
    public void selectAll() {
        // 从数据库获取表所有记录,做数据处理
        baseMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler<MybatisUser>() {
            // 初始化计数器,用于记录当前处理的记录数
            int count = 0;
    
            /**
             * 处理查询结果
             * 此方法在查询到每条记录时被调用,用于处理单个查询结果
             * @param resultContext 包含查询结果的上下文
             */
            @Override
            public void handleResult(ResultContext<? extends MybatisUser> resultContext) {
                // 获取当前处理的用户记录
                MybatisUser mybatisUser = resultContext.getResultObject();
                // 在控制台输出当前处理的记录信息
                System.out.println("当前处理第" + (++count) + "条记录: " + mybatisUser);
            }
    
        });
    
    }

下面是一下常用方法

  • getResultObject: 获取数据库中的每一条记录。
  • getResultCount: 获取当前处理的结果集条数,每处理一条记录,该计数器会加1,计数从1开始。
  • stop: 停止继续处理结果集,相当于在循环中使用 break 语句。

比如当我们需要导出大量数据的情况下,使用普通查询导出是因为一次性把所有数据查询出来放在集合中,这时候垃圾处理器释放不了这一部分内存,如果内存不够就会使程序挂掉。使用mybatis-plus的流式查询, 一边查询一边导出 ,这样用过的数据写入流之后垃圾处理器回收掉内存空间,使内存得到合理应用 。

### 回答1: MybatisPlus流式查询是一种可以大大提高查询效率的查询方式。它允许我们在数据库中逐步获取查询结果,而不是一步到位的将所有结果都加载到内存中。 在MybatisPlus中,我们可以使用LambdaQueryWrapper的stream()方法来实现流式查询。当我们调用stream()方法时,查询条件会被封装成一个Steam查询器。接下来,我们可以通过Steam查询器中的方法,如map()、filter()、sorted()等进行一系列的操作,最终得到所需的查询结果。 MybatisPlus流式查询不仅可以提高查询效率,还可以节约内存占用。在处理大量数据时,使用流式查询可以有效避免OutOfMemoryError等内存溢出问题的发生。 需要注意的是,MybatisPlus流式查询只支持MySQL和PostgreSQL数据库。在使用时,我们还应该根据实际情况选择合适的流式查询方式。如果需要返回实体对象,我们应该使用stream(),如果只需要返回某些字段,则应该使用streamMaps()。 总而言之,MybatisPlus流式查询是一种非常实用的查询方式,可以大幅提高查询效率和减少内存占用。在处理大量数据时,我们应该优先考虑使用流式查询,以提高程序的稳定性和可扩展性。 ### 回答2: Mybatis-PlusMybatis的增强工具包,流式查询是其中的一种特性。它能够为Mybatis-Plus查询结果的及时处理带来更好的效能。 流式查询是指使用流式查询API来进行查询,并通过回调函数对结果进行处理,这种处理方式能够在处理大量数据时,节省内存和提高查询效率。Mybatis-Plus提供了LambdaQueryWrapper和LambdaUpdateWrapper两种流式查询API。 LambdaQueryWrapper是Mybatis-Plus一个受欢迎的查询条件之一,它是基于Java8的Lambda表达式和函数式接口实现的,并包含了所有常规查询条件,如eq等,同时它也支持动态SQL生成。 LambdaUpdateWrapper是基于LambdaQueryWrapper实现的,它用于更新操作时,可以生成update语句的where条件。 使用Lambda函数接口可以优雅地实现流式查询。LambdaQueryWrapper和LambdaUpdateWrapper接口都提供了部分相同的函数方法,如eq()、le()等,在实现查询时,可以直接调用这些方法,而无需手动去书写SQL语句。 同时,因为Lambda表达式语法具有高度的可读性和简洁性,流式查询的代码也更加清晰易懂。 总的来说,Mybatis-Plus流式查询API提供了一种更加高效的查询方式,能够帮助我们在处理大量数据时,提高查询效率和节省内存。 ### 回答3: MybatisPlus是在Mybatis的基础上进行了二次封装,其流式查询MybatisPlus提供的一种高效的查询方式。MybatisPlus流式查询不仅可以减少内存的占用,还可以提高数据查询的效率,特别适用于大数据量的查询场景。 MybatisPlus流式查询可以通过Wrapper<T>构造器中的lambda表达式实现。首先我们需要用lambda表达式构建出一个Wrapper<T>对象,这个对象中包含指定的查询条件。 接下来使用MP提供的stream()方法可轻松实现流式查询。stream()方法返回的是MybatisPlus提供的BaseMapper的Stream实现。 在进行流式查询时,不需要一次性将所有数据读入内存,而是会按照查询条件分步读取数据,这可以显著减少内存开销;此外,流式查询还支持对数据进行排序、分页等操作,有助于提高查询效率。 总之,MybatisPlus流式查询是一种高效、灵活的查询方式,特别适用于大数据量的查询场景。使用流式查询可以减少内存占用,提高查询效率,同时还支持排序、分页等操作,具有很高的实用性和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕德猫宁丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值