強大:MyBatis 流式查詢
點擊上方?java項目開發(fā),選擇?設(shè)為星標
優(yōu)質(zhì)文章,及時送達
--
MyBatis?提供了一個叫?org.apache.ibatis.cursor.Cursor?的接口類用于流式查詢,這個接口繼承了?java.io.Closeable?和?java.lang.Iterable?接口,由此可知:Cursor 是可關(guān)閉的; Cursor 是可遍歷的。
isOpen():用于在取數(shù)據(jù)之前判斷 Cursor 對象是否是打開狀態(tài)。只有當打開時 Cursor 才能取數(shù)據(jù);isConsumed():用于判斷查詢結(jié)果是否全部取完。getCurrentIndex():返回已經(jīng)獲取了多少條數(shù)據(jù)
cursor.forEach(rowObject -> {...});但構(gòu)建 Cursor 的過程不簡單
@Mapper
public interface FooMapper {
????@Select("select * from foo limit #{limit}")
????Cursor scan(@Param("limit") int limit);
} MyBatis?就知道這個查詢方法一個流式查詢。@GetMapping("foo/scan/0/{limit}")
public void scanFoo0(@PathVariable("limit") int limit) throws Exception {
????try?(Cursor 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 cursor =
??????????????sqlSession.getMapper(FooMapper.class).scan(limit) // 2
????) {
????????cursor.forEach(foo -> { });
????}
} 上面的代碼中,1 處我們開啟了一個 SqlSession (實際上也代表了一個數(shù)據(jù)庫連接),并保證它最后能關(guān)閉;2 處我們使用 SqlSession 來獲得 Mapper 對象。這樣才能保證得到的 Cursor 對象是打開狀態(tài)的。
方案二:TransactionTemplate
在 Spring 中,我們可以用 TransactionTemplate 來執(zhí)行一個數(shù)據(jù)庫事務(wù),這個過程中數(shù)據(jù)庫連接同樣是打開的。代碼如下:
@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 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 cursor = fooMapper.scan(limit)) {
????????cursor.forEach(foo -> { });
????}
} @Transactional?注解。這個方案看上去最簡潔,但請注意 Spring 框架當中注解使用的坑:只在外部調(diào)用時生效。在當前類中調(diào)用這個方法,依舊會報錯。-?END - 推薦案例
溫暖提示
為了方便大家更好的學(xué)習(xí),本公眾號經(jīng)常分享一些完整的單個功能案例代碼給大家去練習(xí),如果本公眾號沒有你要學(xué)習(xí)的功能案例,你可以聯(lián)系小編(微信:xxf960513)提供你的小需求給我,我安排我們這邊的開發(fā)團隊免費幫你完成你的案例。 注意:只能提單個功能的需求不能要求功能太多,比如要求用什么技術(shù),有幾個頁面,頁面要求怎么樣?
請長按識別二維碼
想學(xué)習(xí)更多的java功能案例請關(guān)注
Java項目開發(fā)
如果你覺得這個案例以及我們的分享思路不錯,對你有幫助,請分享給身邊更多需要學(xué)習(xí)的朋友。別忘了《留言+點在看》給作者一個鼓勵哦!
評論
圖片
表情


