还在用分页?太Low !试试 MyBatis 流式查询,真心强大!
往期热门文章:
1、告别 swagger-ui ,我选择了这款神器! 2、JDK/Dubbo/Spring 三种 SPI 机制,谁更好? 3、小团队真的适合引入Spring Cloud微服务吗? 4、IDEA 中的热部署神器! 5、我承认 IDEA 2021.3 有点强!
基本概念
MyBatis 流式查询接口
org.apache.ibatis.cursor.Cursor
的接口类用于流式查询,这个接口继承了 java.io.Closeable
和 java.lang.Iterable
接口,由此可知:Cursor 是可关闭的; Cursor 是可遍历的。
isOpen()
:用于在取数据之前判断 Cursor 对象是否是打开状态。只有当打开时 Cursor 才能取数据;isConsumed()
:用于判断查询结果是否全部取完。getCurrentIndex()
:返回已经获取了多少条数据
cursor.forEach(rowObject -> {...});
但构建 Cursor 的过程不简单
@Mapper
public interface FooMapper {
@Select("select * from foo limit #{limit}")
Cursor<Foo> scan(@Param("limit") int limit);
}
scan()
是一个非常简单的查询。通过指定 Mapper 方法的返回值为 Cursor 类型,MyBatis 就知道这个查询方法一个流式查询。@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
}
}
java.lang.IllegalStateException: A Cursor is already closed.
方案一:SqlSessionFactory
@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 -> { });
}
}
方案二: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;
});
}
方案三:@Transactional 注解
@GetMapping("foo/scan/3/{limit}")
@Transactional
public void scanFoo3(@PathVariable("limit") int limit) throws Exception {
try (Cursor<Foo> cursor = fooMapper.scan(limit)) {
cursor.forEach(foo -> { });
}
}
@Transactional
注解。这个方案看上去最简洁,但请注意 Spring 框架当中注解使用的坑:只在外部调用时生效。在当前类中调用这个方法,依旧会报错。
往期热门文章:
1、《历史文章分类导读列表!精选优秀博文都在这里了!》
2、Java必会的工具库,让你的代码量减少90% 3、腾讯最大股东收购了 Stack Overflow,以后“抄代码”都要付费了么? 4、灵隐寺招聘:没有KPI,佛系上班…… 5、如何优雅处理重复请求/并发请求? 6、不用到2038年,MySQL的TIMESTAMP就能把我们系统搞崩! 7、翻车!在项目中用了Arrays.asList、ArrayList的subList,被公开批评 8、想接私活时薪再翻一倍,建议根据这几个开源的Spring Boot项目改改~ 9、细数ThreadLocal三大坑,内存泄露仅是小儿科 10、Redis与MySQL双写一致性如何保证?
评论