返回顶部
首页 > 资讯 > 精选 >MyBatis流式查询的示例分析
  • 214
分享到

MyBatis流式查询的示例分析

2023-06-15 02:06:04 214人浏览 泡泡鱼
摘要

这篇文章主要介绍mybatis流式查询的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!导读:流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低

这篇文章主要介绍mybatis流式查询的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

导读:流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低内存使用

如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好,就无法执行高效的分页查询。因此流式查询是一个数据库访问框架必须具备的功能。
流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:执行一个流式查询后,数据库访问框架就不负责关闭数据库连接了,需要应用在取完数据后自己关闭。

MyBatis 流式查询接口

MyBatis 提供了一个叫 org.apache.ibatis.cursor.Cursor 的接口类用于流式查询,这个接口继承了 java.io.Closeable 和 java.lang.Iterable 接口,由此可知:

  • Cursor 是可关闭的。实际上当关闭 Cursor 时,也一并将数据库连接关闭了;

  • Cursor 是可遍历的。

除此之外,Cursor 还提供了三个方法:

  • isOpen():用于在取数据之前判断 Cursor 对象是否是打开状态。只有当打开时 Cursor 才能取数据;

  • isConsumed():用于判断查询结果是否全部取完;

  • getCurrentIndex():返回已经获取了多少条数据。

因为 Cursor 实现了迭代器接口,因此在实际使用当中,从 Cursor 取数据非常简单:

try(Cursor cursor = mapper.querySomeData()) {    cursor.forEach(rowObject -> {        // ...    });}

使用 try-resource 方式可以令 Cursor 自动关闭。
但构建 Cursor 的过程不简单
我们举个实际例子。下面是一个 Mapper 类:

@Mapperpublic interface FooMapper {    @Select("select * from foo limit #{limit}")    Cursor<Foo> scan(@Param("limit") int limit);}

方法 scan() 是一个非常简单的查询。我们在定义这个方时,指定返回值为 Cursor 类型,MyBatis 就明白这个查询方法是一个流式查询。

然后我们再写一个 springMVC Controller 方法来调用 Mapper(无关的代码已经省略):

@GetMapping("foo/scan/0/{limit}")public void scanFoo0(@PathVariable("limit") int limit) throws Exception {    try (Cursor<Foo> cursor = fooMapper.scan(limit)) {  // 1        cursor.forEach(foo -> {});                      // 2    }}

假设 fooMapper 是 @Autowired 进来的。注释 1 处是获取 Cursor 对象并保证它能最后关闭;2 处则是从 cursor 中取数据。
上面的代码看上去没什么问题,但是执行scanFoo0(int)时会报错:

java.lang.IllegalStateException: A Cursor is already closed.

这是因为我们前面说了在取数据的过程中需要保持数据库连接,而 Mapper 方法通常在执行完后连接就关闭了,因此 Cusor 也一并关闭了。
所以,解决这个问题的思路不复杂,保持数据库连接打开即可。我们至少有三种方案可选。

方案一:sqlSessionFactory

我们可以用 SqlSessionFactory 来手工打开数据库连接,将 Controller 方法修改如下:

@GetMapping("foo/scan/1/{limit}")public void scanFoo1(@PathVariable("limit") int limit) throws Exception {    try (        SqlSession sqlSession = sqlSessionFactory.openSession();  // 1        Cursor<Foo> cursor =               sqlSession.getMapper(FooMapper.class).scan(limit)   // 2    ) {        cursor.forEach(foo -> { });    }}

上面的代码中,1 处我们开启了一个 SqlSession (实际上也代表了一个数据库连接),并保证它最后能关闭;2 处我们使用 SqlSession 来获得 Mapper 对象。这样才能保证得到的 Cursor 对象是打开状态的。

方案二:TransactionTemplate

spring 中,我们可以用 TransactionTemplate 来执行一个数据库事务,这个过程中数据库连接同样是打开的。代码如下:

@GetMapping("foo/scan/2/{limit}")public void scanFoo2(@PathVariable("limit") int limit) throws Exception {    TransactionTemplate transactionTemplate =             new TransactionTemplate(transactionManager);  // 1    transactionTemplate.execute(status -> {               // 2        try (Cursor<Foo> cursor = fooMapper.scan(limit)) {            cursor.forEach(foo -> { });        } catch (IOException e) {            e.printStackTrace();        }        return null;    });}

上面的代码中,1 处我们创建了一个 TransactionTemplate 对象(此处 transactionManager 是怎么来的不用多解释,本文假设读者对 Spring 数据库事务的使用比较熟悉了),2 处执行数据库事务,而数据库事务的内容则是调用 Mapper 对象的流式查询。注意这里的 Mapper 对象无需通过 SqlSession 创建。

方案三:@Transactional 注解

这个本质上和方案二一样,代码如下:

@GetMapping("foo/scan/3/{limit}")@Transactionalpublic void scanFoo3(@PathVariable("limit") int limit) throws Exception {    try (Cursor<Foo> cursor = fooMapper.scan(limit)) {        cursor.forEach(foo -> { });    }}

它仅仅是在原来方法上面加了个 @Transactional 注解。这个方案看上去最简洁,但请注意 Spring 框架当中注解使用的坑:只在外部调用时生效。在当前类中调用这个方法,依旧会报错。

以上是“MyBatis流式查询的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: MyBatis流式查询的示例分析

本文链接: https://lsjlt.com/news/277055.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MyBatis流式查询的示例分析
    这篇文章主要介绍MyBatis流式查询的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!导读:流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低...
    99+
    2023-06-15
  • mybatis-plus查询源码的示例分析
    这篇文章主要介绍mybatis-plus查询源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!配置详情pom.xmldependency>     &...
    99+
    2023-06-29
  • Mybatis查询延迟加载的示例分析
    小编给大家分享一下Mybatis查询延迟加载的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Mybatis查询延迟加载详...
    99+
    2024-04-02
  • Java Fluent Mybatis聚合查询与apply方法流程的示例分析
    这篇文章将为大家详细讲解有关Java Fluent Mybatis聚合查询与apply方法流程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。数据准备为了聚合查询的条件,添加了几条数据。MIN我们...
    99+
    2023-06-25
  • mybatis-plus 流式查询
    mybatis 一次从数据库查询太多数据,导致数据库挂了,这里使用流式查询,每次查询500条数据,对所有数据进行遍历: 这里写在Mapper.java(如下 JOB_GZS 是数据库表,JobGzs ...
    99+
    2023-08-31
    mybatis java mysql
  • spring中mybatis多表查询处理的示例分析
    这篇文章将为大家详细讲解有关spring中mybatis多表查询处理的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。package com.swhy.bw.advisor.center....
    99+
    2023-06-02
  • LINQ查询的示例分析
    这篇文章主要介绍LINQ查询的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在之前的C#版中,开发者应用许多不同的查询语言来访问不同的数据源。例如,要查询一个XML文件,开发者会使用XPath,要查询一个SQ...
    99+
    2023-06-17
  • OJB查询的示例分析
    这篇文章主要为大家展示了“OJB查询的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“OJB查询的示例分析”这篇文章吧。OJB查询该文档介绍了不同查询机制的使用。文档中的代码都通过Juni...
    99+
    2023-06-03
  • MyBatis-Plus 分页查询的实现示例
    方法: 使用selectPage()方法,第一个参数是传入分页方法(传入当前页和当前显示多少条数据),第二个参数是传入查询条件(如果查询全部的话,可以传null)。 前提: 表中的...
    99+
    2024-04-02
  • Oracle分页查询的示例分析
    这篇文章主要介绍Oracle分页查询的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Oracle分页查询的实例详解1.Oracle分页查询:SELECT *...
    99+
    2024-04-02
  • ajax分页查询的示例分析
    这篇文章主要为大家展示了“ajax分页查询的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ajax分页查询的示例分析”这篇文章吧。(1)先写个显示数据的...
    99+
    2024-04-02
  • innodb查询锁的示例分析
    这篇文章主要为大家展示了“innodb查询锁的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“innodb查询锁的示例分析”这篇文章吧。 ...
    99+
    2024-04-02
  • MySQL数据查询之子查询的示例分析
    这篇文章主要介绍了MySQL数据查询之子查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。子查询是指一个查询语句嵌套在另一个查询语...
    99+
    2024-04-02
  • Mybatis应用mysql存储过程查询数据的示例分析
    小编给大家分享一下Mybatis应用mysql存储过程查询数据的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.创建mysql存储过程,这是个复杂查询加...
    99+
    2023-05-30
  • MySQL联合查询的示例分析
    这篇文章给大家分享的是有关MySQL联合查询的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。笛卡尔积笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian ...
    99+
    2024-04-02
  • MySQL查询优化的示例分析
    小编给大家分享一下MySQL查询优化的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、优化的思路和原则有哪些1、 优化更需要优化的查询 2、 定位优化对象的性能瓶颈 3、 明确优...
    99+
    2024-04-02
  • mysql树状查询的示例分析
    这篇文章主要为大家展示了“mysql树状查询的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysql树状查询的示例分析”这篇文章吧。--创建表dro&...
    99+
    2024-04-02
  • Oracle查询脚本的示例分析
    这篇文章将为大家详细讲解有关Oracle查询脚本的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 --查询回滚段信息selec ...
    99+
    2024-04-02
  • MySql连接查询的示例分析
    这篇文章主要介绍了MySql连接查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。MySql连接查询精解 出于对知识的总...
    99+
    2024-04-02
  • CSS容器查询的示例分析
    这篇文章给大家分享的是有关CSS容器查询的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在前端开发中经常需要按不同屏幕尺寸来进设计达到PC和移动端响应式。我们一般使用CSS媒体查询来检测视口宽度或高度,然...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作