MyBatis流式查询的使用


相关概念


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

如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好,就无法执行高效的分页查询。因此流式查询是一个数据库访问框架必须具备的功能。

流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:执行一个流式查询后,数据库访问框架就不负责关闭数据库连接了,需要应用在取完数据后自己关闭。

MyBatis 提供了一个叫 org.apache.ibatis.cursor.Cursor 的接口类用于流式查询,这个接口继承了
java.io.Closeable 和 java.lang.Iterable 接口,由此可知: 1、Cursor 是可关闭的;
2、Cursor 是可遍历的。 除此之外,Cursor 还提供了三个方法: 1、isOpen():用于在取数据之前判断 Cursor
对象是否是打开状态。只有当打开时 Cursor 才能取数据; 2、isConsumed():用于判断查询结果是否全部取完。
3、getCurrentIndex():返回已经获取了多少条数据


代码


SQL建表:
CREATE TABLE `student` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `gender` bit(1) NOT NULL,
  `email` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4;
实体类:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private Integer id;

    private String name;

    private Boolean gender;

    private String email;

    private String phone;

}
Controller(省略Service):
@RestController
public class StudentController {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;


    @GetMapping("/all")
    public String findAllStream() {
        try (
                // 使用 sqlSession 手动获取 Mapper 对象,否则会出现 "A Cursor is already closed" 异常
                SqlSession sqlSession = sqlSessionFactory.openSession();
                Cursor<Student> cursor = sqlSession.getMapper(StudentMapper.class).findAllStream()
        ) {
            cursor.forEach(student -> {
                System.out.println(student);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }

}
Mapper:
@Mapper
public interface StudentMapper {

    Cursor<Student> findAllStream();

}
StudentMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper">

    <resultMap id="BaseResultMap" type="com.example.entity.Student">
        <result column="id" property="id" />
        <result column="name" property="name" />
        <result column="gender" property="gender" />
        <result column="email" property="email" />
        <result column="phone" property="phone" />
    </resultMap>

    <select id="findAllStream" resultMap="BaseResultMap" fetchSize="2">
        select * from student
    </select>

</mapper>

参考:
https://www.cnblogs.com/ooo0/p/14167883.html
https://blog.csdn.net/iku5200/article/details/82856621
https://www.jianshu.com/p/c539b6d3ed90

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值