91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MyBatis流式查詢輕松幫你解決分頁(yè)慢的問(wèn)題

5jek_harmonyos ? 來(lái)源:思否開(kāi)發(fā)者社區(qū) ? 作者:捏造的信仰 ? 2021-08-04 15:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者丨捏造的信仰

segmentfault.com/a/1190000022478915

Part1基本概念

流式查詢指的是查詢成功后不是返回一個(gè)集合而是返回一個(gè)迭代器,應(yīng)用每次從迭代器取一條查詢結(jié)果。流式查詢的好處是能夠降低內(nèi)存使用。

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

流式查詢的過(guò)程當(dāng)中,數(shù)據(jù)庫(kù)連接是保持打開(kāi)狀態(tài)的,因此要注意的是:執(zhí)行一個(gè)流式查詢后,數(shù)據(jù)庫(kù)訪問(wèn)框架就不負(fù)責(zé)關(guān)閉數(shù)據(jù)庫(kù)連接了,需要應(yīng)用在取完數(shù)據(jù)后自己關(guān)閉。

Part2MyBatis 流式查詢接口

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

Cursor 是可關(guān)閉的。實(shí)際上當(dāng)關(guān)閉 Cursor 時(shí),也一并將數(shù)據(jù)庫(kù)連接關(guān)閉了;

Cursor 是可遍歷的。

除此之外,Cursor 還提供了三個(gè)方法:

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

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

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

因?yàn)?Cursor 實(shí)現(xiàn)了迭代器接口,因此在實(shí)際使用當(dāng)中,從 Cursor 取數(shù)據(jù)非常簡(jiǎn)單:

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

cursor.forEach(rowObject -》 {

// 。。。

});

}

使用 try-resource 方式可以令 Cursor 自動(dòng)關(guān)閉。

Part3但構(gòu)建 Cursor 的過(guò)程不簡(jiǎn)單

我們舉個(gè)實(shí)際例子。下面是一個(gè) Mapper 類:

@Mapper

public interface FooMapper {

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

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

}

方法 scan() 是一個(gè)非常簡(jiǎn)單的查詢。我們?cè)诙x這個(gè)方時(shí),指定返回值為 Cursor 類型,MyBatis 就明白這個(gè)查詢方法是一個(gè)流式查詢。

然后我們?cè)賹?xiě)一個(gè) SpringMVC Controller 方法來(lái)調(diào)用 Mapper(無(wú)關(guān)的代碼已經(jīng)省略):

@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

}

}

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

上面的代碼看上去沒(méi)什么問(wèn)題,但是執(zhí)行 scanFoo0(int) 時(shí)會(huì)報(bào)錯(cuò):

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

這是因?yàn)槲覀兦懊嬲f(shuō)了在取數(shù)據(jù)的過(guò)程中需要保持?jǐn)?shù)據(jù)庫(kù)連接,而 Mapper 方法通常在執(zhí)行完后連接就關(guān)閉了,因此 Cusor 也一并關(guān)閉了。

所以,解決這個(gè)問(wèn)題的思路不復(fù)雜,保持?jǐn)?shù)據(jù)庫(kù)連接打開(kāi)即可。我們至少有三種方案可選。

方案一:SqlSessionFactory

我們可以用 SqlSessionFactory 來(lái)手工打開(kāi)數(shù)據(jù)庫(kù)連接,將 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 處我們開(kāi)啟了一個(gè) SqlSession (實(shí)際上也代表了一個(gè)數(shù)據(jù)庫(kù)連接),并保證它最后能關(guān)閉;2 處我們使用 SqlSession 來(lái)獲得 Mapper 對(duì)象。這樣才能保證得到的 Cursor 對(duì)象是打開(kāi)狀態(tài)的。

方案二:TransactionTemplate

在 Spring 中,我們可以用 TransactionTemplate 來(lái)執(zhí)行一個(gè)數(shù)據(jù)庫(kù)事務(wù),這個(gè)過(guò)程中數(shù)據(jù)庫(kù)連接同樣是打開(kāi)的。代碼如下:

@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)建了一個(gè) TransactionTemplate 對(duì)象(此處 transactionManager 是怎么來(lái)的不用多解釋,本文假設(shè)讀者對(duì) Spring 數(shù)據(jù)庫(kù)事務(wù)的使用比較熟悉了),2 處執(zhí)行數(shù)據(jù)庫(kù)事務(wù),而數(shù)據(jù)庫(kù)事務(wù)的內(nèi)容則是調(diào)用 Mapper 對(duì)象的流式查詢。注意這里的 Mapper 對(duì)象無(wú)需通過(guò) SqlSession 創(chuàng)建。

方案三:@Transactional 注解

這個(gè)本質(zhì)上和方案二一樣,代碼如下:

@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 -》 { });

}

}

它僅僅是在原來(lái)方法上面加了個(gè) @Transactional 注解。這個(gè)方案看上去最簡(jiǎn)潔,但請(qǐng)注意 Spring 框架當(dāng)中注解使用的坑:只在外部調(diào)用時(shí)生效。在當(dāng)前類中調(diào)用這個(gè)方法,依舊會(huì)報(bào)錯(cuò)。

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

編輯:jq

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

    關(guān)注

    0

    文章

    64

    瀏覽量

    7139

原文標(biāo)題:還在擔(dān)心分頁(yè)慢嗎? MyBatis 流式查詢解決你的煩惱

文章出處:【微信號(hào):harmonyos_developer,微信公眾號(hào):harmonyos_developer】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Redis內(nèi)存管理、持久化策略與查詢排查分析

    Redis 在生產(chǎn)環(huán)境中承擔(dān)著緩存、會(huì)話存儲(chǔ)、消息隊(duì)列、分布式鎖等多種角色。隨著數(shù)據(jù)量增長(zhǎng)和并發(fā)壓力上升,內(nèi)存碎片、持久化 I/O 抖動(dòng)、查詢堆積這三類問(wèn)題會(huì)逐漸顯現(xiàn),直接影響服務(wù)延遲和穩(wěn)定性。Redis 8.x 在內(nèi)存管理和持久化機(jī)制上做了若干改進(jìn),但核心調(diào)優(yōu)思路與
    的頭像 發(fā)表于 02-27 11:00 ?131次閱讀

    RUI Builder 圖形化UI設(shè)計(jì)工具

    RUI Builder 圖形化UI設(shè)計(jì)工具 該軟件為圖形化UI設(shè)計(jì)軟件,搭配瑞佑圖形處理器,輕松設(shè)計(jì)UI界面!主要特色功能: 在PC上直接設(shè)計(jì)界面,再生成UI渲染源碼(.c),程序中直接引用即可
    發(fā)表于 12-12 20:14

    微店商品列表API,輕松采集商品列表數(shù)據(jù)

    微店商品列表API是微店開(kāi)放平臺(tái)提供的核心接口,主要用于獲取指定店鋪的商品列表數(shù)據(jù)。該接口支持分頁(yè)查詢、條件篩選和排序功能,適用于電商管理系統(tǒng)、競(jìng)品分析和多平臺(tái)展示等場(chǎng)景。 一、接口概述 1.
    的頭像 發(fā)表于 12-01 14:32 ?436次閱讀

    商品類目屬性查詢接口技術(shù)實(shí)現(xiàn)詳解

    ? ? 一、接口核心功能 該接口用于查詢電商系統(tǒng)中商品類目的屬性信息,支持: 按類目ID查詢屬性集合 按屬性類型過(guò)濾(關(guān)鍵屬性$K$、銷售屬性$S$、普通屬性$N$) 分頁(yè)返回屬性數(shù)據(jù) 多語(yǔ)言屬性名
    的頭像 發(fā)表于 10-11 15:43 ?458次閱讀
    商品類目屬性<b class='flag-5'>查詢</b>接口技術(shù)實(shí)現(xiàn)詳解

    別踩分頁(yè)坑!京東商品詳情接口實(shí)戰(zhàn)指南:從并發(fā)優(yōu)化到數(shù)據(jù)完整性閉環(huán)

    京東商品詳情接口(jingdong.ware.get)是電商數(shù)據(jù)開(kāi)發(fā)的核心難點(diǎn),本文詳解其權(quán)限申請(qǐng)、分頁(yè)優(yōu)化、多規(guī)格遞歸解析與完整性校驗(yàn)等實(shí)戰(zhàn)方案,結(jié)合代碼示例與性能調(diào)優(yōu)參數(shù),助你高效穩(wěn)定對(duì)接,提升數(shù)據(jù)獲取效率2.5倍以上,適用于各類規(guī)模店鋪的數(shù)據(jù)需求。
    的頭像 發(fā)表于 09-30 15:50 ?1097次閱讀

    常用PromQL查詢案例總結(jié)

    在云原生時(shí)代,Prometheus已經(jīng)成為監(jiān)控領(lǐng)域的事實(shí)標(biāo)準(zhǔn)。作為一名資深運(yùn)維工程師,我見(jiàn)過(guò)太多團(tuán)隊(duì)在PromQL查詢上踩坑,也見(jiàn)過(guò)太多因?yàn)楸O(jiān)控不到位導(dǎo)致的生產(chǎn)事故。今天分享10個(gè)實(shí)戰(zhàn)中最常用的PromQL查詢案例,每一個(gè)都是血淚經(jīng)驗(yàn)的總結(jié)。
    的頭像 發(fā)表于 09-18 14:54 ?718次閱讀

    數(shù)據(jù)庫(kù)查詢分析與SQL優(yōu)化實(shí)戰(zhàn)技巧

    今天,我將分享我在處理數(shù)千次數(shù)據(jù)庫(kù)性能問(wèn)題中積累的實(shí)戰(zhàn)經(jīng)驗(yàn),幫助你系統(tǒng)掌握查詢分析與SQL優(yōu)化的核心技巧。無(wú)論你是剛?cè)腴T(mén)的運(yùn)維新手,還是有一定經(jīng)驗(yàn)的工程師,這篇文章都將為你提供實(shí)用的解決方案。
    的頭像 發(fā)表于 09-08 09:34 ?976次閱讀

    MySQL查詢優(yōu)化案例

    凌晨3點(diǎn),手機(jī)瘋狂震動(dòng)。監(jiān)控告警顯示:核心業(yè)務(wù)接口響應(yīng)時(shí)間超過(guò)20秒,用戶投訴如潮水般涌來(lái)。這是每個(gè)運(yùn)維工程師的噩夢(mèng)時(shí)刻。
    的頭像 發(fā)表于 08-27 14:49 ?711次閱讀

    MySQL查詢終極優(yōu)化指南

    作為一名在生產(chǎn)環(huán)境摸爬滾打多年的運(yùn)維工程師,我見(jiàn)過(guò)太多因?yàn)?b class='flag-5'>慢查詢導(dǎo)致的線上故障。今天分享一套經(jīng)過(guò)實(shí)戰(zhàn)檢驗(yàn)的MySQL查詢分析與索引優(yōu)化方法論,幫你
    的頭像 發(fā)表于 08-13 15:55 ?846次閱讀

    產(chǎn)品詳情查詢API接口

    ? 在現(xiàn)代電子商務(wù)和軟件開(kāi)發(fā)中,產(chǎn)品詳情查詢API接口扮演著至關(guān)重要的角色。它允許開(kāi)發(fā)者通過(guò)編程方式從遠(yuǎn)程服務(wù)器獲取產(chǎn)品的詳細(xì)信息,如名稱、價(jià)格、描述和庫(kù)存狀態(tài)等。這種接口通常基于RESTful架構(gòu)
    的頭像 發(fā)表于 07-24 14:39 ?579次閱讀
    產(chǎn)品詳情<b class='flag-5'>查詢</b>API接口

    簡(jiǎn)要分析限流式保護(hù)器在某無(wú)人駕駛汽車充電站的應(yīng)用

    摘 要:交流充電樁俗稱“充樁”,固定安裝在電動(dòng)汽車外、與交流電網(wǎng)連接,國(guó)標(biāo)采用 220V單相交流電,為電動(dòng)汽車車載充電機(jī)(即固定安裝在電動(dòng)汽車上的充電機(jī))提供交流電源的供電裝置。國(guó)家標(biāo)準(zhǔn)
    的頭像 發(fā)表于 07-08 14:28 ?578次閱讀
    簡(jiǎn)要分析限<b class='flag-5'>流式</b>保護(hù)器在某無(wú)人駕駛汽車充電站的應(yīng)用

    科普|公司的Wi-Fi,為什么這么?

    好了,也搞不定。這是為什么呢?公司的Wi-Fi,到底有什么“苦衷”?█Wi-Fi速率為什么這么?Wi-Fi速度,其實(shí)說(shuō)白了,就兩種原因:一是北向的出口帶寬小。水
    的頭像 發(fā)表于 06-20 06:06 ?1517次閱讀
    科普|公司的Wi-Fi,為什么這么<b class='flag-5'>慢</b>?

    HarmonyOS5云服務(wù)技術(shù)分享--云數(shù)據(jù)庫(kù)使用指南

    (\"price\") .get(); ??分頁(yè)查詢??(跳過(guò)前5條,取10條): query() .lessThan(\"price\", 50
    發(fā)表于 05-22 18:29

    ASCP310系列電氣防火限流式保護(hù)器安裝使用說(shuō)明書(shū) V1.2

    ASCP310 系列電氣防火限流式保護(hù)器是安科瑞電氣專為中低壓配電系統(tǒng)設(shè)計(jì)的智能保護(hù)設(shè)備,主要應(yīng)用于電動(dòng)汽車充電站、工業(yè)配電、商業(yè)建筑等場(chǎng)景。針對(duì)傳統(tǒng)斷路器短路響應(yīng)、電弧危害大等問(wèn)題,該保護(hù)器以微秒級(jí)速度快速限制短路電流,實(shí)現(xiàn)滅弧保護(hù),顯著降低電氣火災(zāi)風(fēng)險(xiǎn),保障用電安全
    發(fā)表于 05-17 17:32 ?2次下載

    充電樁用限流式保護(hù)器怎么選擇?

    簡(jiǎn)婷 安科瑞電氣股份有限公司 上海嘉定? 201801 技術(shù)支持18701998775? 電氣防火限流式保護(hù)器 ? ?電氣防火限流式保護(hù)器是一種電氣保護(hù)設(shè)備,通常用于防止電氣設(shè)備過(guò)載、短路、接地故障
    的頭像 發(fā)表于 04-11 13:10 ?1051次閱讀
    充電樁用限<b class='flag-5'>流式</b>保護(hù)器怎么選擇?