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的流式查询, 一边查询一边导出 ,这样用过的数据写入流之后垃圾处理器回收掉内存空间,使内存得到合理应用 。
到此这篇关于MyBatis-Plus流式查询的实现示例的文章就介绍到这了,更多相关MyBatis-Plus流式查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论