那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MyBatis流式查詢輕松幫你解決分頁慢的問題

5jek_harmonyos ? 來源:思否開發(fā)者社區(qū) ? 作者:捏造的信仰 ? 2021-08-04 15:52 ? 次閱讀

作者丨捏造的信仰

segmentfault.com/a/1190000022478915

Part1基本概念

流式查詢指的是查詢成功后不是返回一個集合而是返回一個迭代器,應用每次從迭代器取一條查詢結果。流式查詢的好處是能夠降低內存使用。

如果沒有流式查詢,我們想要從數(shù)據庫取 1000 萬條記錄而又沒有足夠的內存時,就不得不分頁查詢,而分頁查詢效率取決于表設計,如果設計的不好,就無法執(zhí)行高效的分頁查詢。因此流式查詢是一個數(shù)據庫訪問框架必須具備的功能。

流式查詢的過程當中,數(shù)據庫連接是保持打開狀態(tài)的,因此要注意的是:執(zhí)行一個流式查詢后,數(shù)據庫訪問框架就不負責關閉數(shù)據庫連接了,需要應用在取完數(shù)據后自己關閉。

Part2MyBatis 流式查詢接口

MyBatis 提供了一個叫 org.apache.ibatis.cursor.Cursor 的接口類用于流式查詢,這個接口繼承了 java.io.Closeable 和 java.lang.Iterable 接口,由此可知:

Cursor 是可關閉的。實際上當關閉 Cursor 時,也一并將數(shù)據庫連接關閉了;

Cursor 是可遍歷的。

除此之外,Cursor 還提供了三個方法:

isOpen():用于在取數(shù)據之前判斷 Cursor 對象是否是打開狀態(tài)。只有當打開時 Cursor 才能取數(shù)據;

isConsumed():用于判斷查詢結果是否全部取完;

getCurrentIndex():返回已經獲取了多少條數(shù)據。

因為 Cursor 實現(xiàn)了迭代器接口,因此在實際使用當中,從 Cursor 取數(shù)據非常簡單:

try(Cursor cursor = mapper.querySomeData()) {

cursor.forEach(rowObject -》 {

// 。。。

});

}

使用 try-resource 方式可以令 Cursor 自動關閉。

Part3但構建 Cursor 的過程不簡單

我們舉個實際例子。下面是一個 Mapper 類:

@Mapper

public interface FooMapper {

@Select(“select * from foo limit #{limit}”)

Cursor《Foo》 scan(@Param(“l(fā)imit”) int limit);

}

方法 scan() 是一個非常簡單的查詢。我們在定義這個方時,指定返回值為 Cursor 類型,MyBatis 就明白這個查詢方法是一個流式查詢。

然后我們再寫一個 SpringMVC Controller 方法來調用 Mapper(無關的代碼已經省略):

@GetMapping(“foo/scan/0/{limit}”)

public void scanFoo0(@PathVariable(“l(fā)imit”) int limit) throws Exception {

try (Cursor《Foo》 cursor = fooMapper.scan(limit)) { // 1

cursor.forEach(foo -》 {}); // 2

}

}

假設 fooMapper 是 @Autowired 進來的。注釋 1 處是獲取 Cursor 對象并保證它能最后關閉;2 處則是從 cursor 中取數(shù)據。

上面的代碼看上去沒什么問題,但是執(zhí)行 scanFoo0(int) 時會報錯:

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

這是因為我們前面說了在取數(shù)據的過程中需要保持數(shù)據庫連接,而 Mapper 方法通常在執(zhí)行完后連接就關閉了,因此 Cusor 也一并關閉了。

所以,解決這個問題的思路不復雜,保持數(shù)據庫連接打開即可。我們至少有三種方案可選。

方案一:SqlSessionFactory

我們可以用 SqlSessionFactory 來手工打開數(shù)據庫連接,將 Controller 方法修改如下:

@GetMapping(“foo/scan/1/{limit}”)

public void scanFoo1(@PathVariable(“l(fā)imit”) 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 (實際上也代表了一個數(shù)據庫連接),并保證它最后能關閉;2 處我們使用 SqlSession 來獲得 Mapper 對象。這樣才能保證得到的 Cursor 對象是打開狀態(tài)的。

方案二:TransactionTemplate

在 Spring 中,我們可以用 TransactionTemplate 來執(zhí)行一個數(shù)據庫事務,這個過程中數(shù)據庫連接同樣是打開的。代碼如下:

@GetMapping(“foo/scan/2/{limit}”)

public void scanFoo2(@PathVariable(“l(fā)imit”) 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 處我們創(chuàng)建了一個 TransactionTemplate 對象(此處 transactionManager 是怎么來的不用多解釋,本文假設讀者對 Spring 數(shù)據庫事務的使用比較熟悉了),2 處執(zhí)行數(shù)據庫事務,而數(shù)據庫事務的內容則是調用 Mapper 對象的流式查詢。注意這里的 Mapper 對象無需通過 SqlSession 創(chuàng)建。

方案三:@Transactional 注解

這個本質上和方案二一樣,代碼如下:

@GetMapping(“foo/scan/3/{limit}”)

@Transactional

public void scanFoo3(@PathVariable(“l(fā)imit”) int limit) throws Exception {

try (Cursor《Foo》 cursor = fooMapper.scan(limit)) {

cursor.forEach(foo -》 { });

}

}

它僅僅是在原來方法上面加了個 @Transactional 注解。這個方案看上去最簡潔,但請注意 Spring 框架當中注解使用的坑:只在外部調用時生效。在當前類中調用這個方法,依舊會報錯。

以上是三種實現(xiàn) MyBatis 流式查詢的方法。

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mybatis
    +關注

    關注

    0

    文章

    62

    瀏覽量

    6745

原文標題:還在擔心分頁慢嗎? MyBatis 流式查詢解決你的煩惱

文章出處:【微信號:harmonyos_developer,微信公眾號:harmonyos_developer】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    老舊小區(qū)充電樁限流式保護器的應用

    摘要? ?隨著城市化進程的推進,老舊小區(qū)的電氣設施逐漸顯現(xiàn)出無法滿足現(xiàn)代用電需求的局面。特別是在老舊小區(qū)進行用電改造時,電氣安全問題尤為突出。傳統(tǒng)的電氣保護設備在短路和過載保護方面存在響應、壽命短
    的頭像 發(fā)表于 01-06 14:34 ?168次閱讀
    老舊小區(qū)充電樁限<b class='flag-5'>流式</b>保護器的應用

    Mybatis 攔截器實現(xiàn)單數(shù)據源內多數(shù)據庫切換

    作者:京東保險 王奕龍 物流的分揀業(yè)務在某些分揀場地只有一個數(shù)據源,因為數(shù)據量比較大,將所有數(shù)據存在一張表內查詢速度,也為了做不同設備數(shù)據的分庫管理,便在這個數(shù)據源內創(chuàng)建了多個不同庫名但表完全相同
    的頭像 發(fā)表于 12-12 10:23 ?881次閱讀

    什么是虛擬內存分頁 Windows系統(tǒng)虛擬內存優(yōu)化方法

    虛擬內存分頁概述 在Windows操作系統(tǒng)中,虛擬內存是通過分頁機制實現(xiàn)的。分頁允許系統(tǒng)將內存中的數(shù)據移動到硬盤上,以便為當前運行的程序騰出空間。這個過程對于保持系統(tǒng)的流暢運行至關重要,尤其是在物理
    的頭像 發(fā)表于 12-04 09:16 ?593次閱讀

    Simplelink? CC3220-OV788音頻/視頻流式傳輸參考

    電子發(fā)燒友網站提供《Simplelink? CC3220-OV788音頻/視頻流式傳輸參考.pdf》資料免費下載
    發(fā)表于 09-02 11:13 ?0次下載
    Simplelink? CC3220-OV788音頻/視頻<b class='flag-5'>流式</b>傳輸參考

    滑動變阻器限流式分壓式接法區(qū)別

    滑動變阻器是一種常見的電子元件,用于調節(jié)電路中的電阻值。在實際應用中,滑動變阻器的接法主要有兩種:限流式和分壓式。這兩種接法在電路設計和應用中有著不同的優(yōu)缺點和適用范圍。 一、限流式接法 工作原理
    的頭像 發(fā)表于 08-05 14:37 ?3994次閱讀

    流式滑動變阻器的選型原則

    流式滑動變阻器,又稱為限流電阻器或限流電位器,是一種用于限制電路中電流大小的電子元件。在電子電路設計中,選擇合適的限流式滑動變阻器對于確保電路的穩(wěn)定運行和提高電路性能至關重要。 一、限流式滑動
    的頭像 發(fā)表于 08-05 14:31 ?1062次閱讀

    流式傳感器的主要優(yōu)點是什么

    流式傳感器是一種基于渦流原理的非接觸式傳感器,廣泛應用于工業(yè)自動化、航空航天、能源、交通等領域。它具有許多優(yōu)點,使得其在眾多傳感器類型中脫穎而出。 1. 非接觸式測量 渦流式傳感器的工作原理是通過
    的頭像 發(fā)表于 07-26 15:10 ?1009次閱讀

    使用mybatis切片實現(xiàn)數(shù)據權限控制

    一、使用方式 數(shù)據權限控制需要對查詢出的數(shù)據進行篩選,對業(yè)務入侵最少的方式就是利用mybatis或者數(shù)據庫連接池的切片對已有業(yè)務的sql進行修改。切片邏輯完成后,僅需要在業(yè)務中加入少量標記代碼
    的頭像 發(fā)表于 07-09 17:26 ?444次閱讀
    使用<b class='flag-5'>mybatis</b>切片實現(xiàn)數(shù)據權限控制

    流式繼電器工作特性有哪些

    流式繼電器是一種利用整流原理實現(xiàn)繼電器觸點切換的電子元件,廣泛應用于電力系統(tǒng)、工業(yè)自動化、通信設備等領域。 整流式繼電器的工作原理 整流式繼電器的工作原理基于整流原理。當輸入電壓達到一定值
    的頭像 發(fā)表于 06-28 10:26 ?882次閱讀

    流式繼電器輸入的是什么電源

    流式繼電器是一種常見的電氣元件,廣泛應用于電力系統(tǒng)、工業(yè)自動化、通信設備等領域。它的核心功能是將輸入的交流電源轉換為直流電源,以驅動繼電器的線圈,實現(xiàn)對電路的控制。本文將詳細介紹整流式繼電器
    的頭像 發(fā)表于 06-28 10:21 ?908次閱讀

    流式繼電器與無極繼電器的區(qū)別

    在電氣工程和自動化領域,繼電器是一種非常重要的控制元件。繼電器的主要作用是接收輸入信號,然后根據輸入信號的狀態(tài)來控制輸出電路的通斷。根據其工作原理和結構特點,繼電器可以分為很多種類,其中整流式繼電器
    的頭像 發(fā)表于 06-28 10:17 ?1144次閱讀

    流式繼電器結構上有哪些特點

    流式繼電器是一種利用整流原理來實現(xiàn)繼電器動作的電氣設備,廣泛應用于電力系統(tǒng)、工業(yè)自動化、通信設備等領域。本文將詳細介紹整流式繼電器的結構特點,包括其工作原理、主要組成部分、性能指標、應用場景等方面
    的頭像 發(fā)表于 06-28 10:15 ?1135次閱讀

    流式繼電器屬于什么繼電器

    流式繼電器是一種特殊類型的繼電器,它主要用于將交流電轉換為直流電。這種繼電器在許多應用中都非常重要,例如在電力系統(tǒng)中,它可以用于控制和保護設備。在本文中,我們將詳細介紹整流式繼電器的工作原理、類型
    的頭像 發(fā)表于 06-28 10:07 ?861次閱讀

    分庫分表后復雜查詢的應對之道:基于DTS實時性ES寬表構建技術實踐

    分表,通過分庫分表應對存系統(tǒng)讀寫性能瓶頸和存儲瓶頸;分庫分表幫我們解決問題的同時,也帶來了復雜性;比如多條件的分頁查詢,多條件的聯(lián)表查詢變得復雜起來,通過調研我們發(fā)現(xiàn)針對這些分頁,聯(lián)表
    的頭像 發(fā)表于 06-25 18:30 ?911次閱讀
    分庫分表后復雜<b class='flag-5'>查詢</b>的應對之道:基于DTS實時性ES寬表構建技術實踐

    影響電動汽車交流充時間的因素有哪些?

    影響電動汽車交流充時間的因素有哪些? 電動汽車的充時間受到多個因素的影響。下面將詳細介紹這些因素,并解釋它們是如何影響充時間的。 首先,電動汽車的充時間受到電動汽車電池的容量的
    的頭像 發(fā)表于 04-08 16:13 ?1334次閱讀
    六合彩报纸| 巴特百家乐官网的玩法技巧和规则| 大连百家乐商场| 百家乐出闲几率| 2013现金棋牌游戏| 立博百家乐游戏| 新澳博天上人间娱乐| 太阳城百家乐杀祖玛| 嵊泗县| 上市百家乐评论| 七乐百家乐官网现金网| 百家乐平台有什么优惠| 百家乐官网画面| 星空棋牌下载| 百家乐太阳城怎么样| 百家乐官网神仙道官网| 88娱乐城备用网址| 大发888游戏平台hana| 巴宝莉百家乐的玩法技巧和规则| 最好的百家乐官网好评平台都有哪些| 大发888娱乐城游戏下载| 百家乐投注双赢技巧| 百家乐官网2号技术| 同乐城备用| 百家乐官网娱乐城官方网| 博彩评级网| 互联网百家乐的玩法技巧和规则 | 东阿县| 太阳城线上真人娱乐| 在线百家乐平台| A8百家乐官网娱乐| 百家乐官网投注法减注| 大发888体育真人| 百家乐打鱼秘籍| 百家乐官网园好又多| 百家乐官网投注杀手| 赌场风云国语| 大发888娱乐登陆| 百家乐可以出千吗| 百家乐怎打能赢| 钱隆百家乐官网破解版|