精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

SpringBoot+Mybatis如何實現流式查詢?

jf_ro2CN3Fa ? 來源:CSDN ? 2023-06-12 09:57 ? 次閱讀

什么是mybatis流式查詢?

使用mybatis作為持久層的框架時,通過mybatis執行查詢數據的請求執行成功后,mybatis返回的結果集不是一個集合或對象,而是一個迭代器,可以通過遍歷迭代器來取出結果集,避免一次性取出大量的數據而占用太多的內存。

Cursor

org.apache.ibatis.cursor.Cursor接口有三個抽象方法,分別是

isOpen() :判斷cursor是否正處于打開狀態;

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

getCurrentIndex() :查詢已讀取數據在全部數據里的索引位置;

publicinterfaceCursorextendsCloseable,Iterable{
//判斷cursor是否正處于打開狀態
//當返回true,則表示cursor已經開始從數據庫里刷新數據了;
booleanisOpen();
//判斷查詢結果是否全部讀取完;
//當返回true,則表示查詢sql匹配的全部數據都消費完了;
booleanisConsumed();
//查詢已讀取數據在全部數據里的索引位置;
//第一條數據的索引位置為0;當返回索引位置為-1時,則表示已經沒有數據可以讀取;
intgetCurrentIndex();
}

代碼實現

mybatis的所謂流式查詢,就是服務端程序查詢數據的過程中,與遠程數據庫一直保持連接,不斷的去數據庫拉取數據,提交事務并關閉sqlsession后,數據庫連接斷開,停止數據拉取,需要注意的是使用這種方式,需要自己手動維護sqlsession和事務的提交。

1、實現方式很簡單,原來返回的類型是集合或對象,流式查詢返回的的類型Curor,泛型內表示實際的類型,其他沒有變化;

@Mapper
publicinterfacePersonDao{
CursorselectByCursor();
IntegerqueryCount();

}

select*fromsys_personorderbyiddesc


selectcount(*)fromsys_person

2、dao層向service層返回的是Cursor類型對象,只要不提交關閉sqlsession,服務端程序就可以一直從數據數據庫讀取數據,直到查詢sql匹配到數據全部讀取完;

示例里的主要業務邏輯是:從sys_person表中讀取所有的人員信息數據,然后按照每1000條數據為一組,讀取到內存里進行處理,以此類推,直到查詢sql匹配到數據全部處理完,再提交事務,關閉sqlSession;

@Service
@Slf4j
publicclassPersonServiceImplimplementsIPersonService{
@Autowired
privateSqlSessionFactorysqlSessionFactory;

@Override
publicvoidgetOneByAsync()throwsInterruptedException{
newThread(newRunnable(){
@SneakyThrows
@Override
publicvoidrun(){
//使用sqlSessionFactory打開一個sqlSession,在沒有讀取完數據之前不要提交事務或關閉sqlSession
log.info("----開啟sqlSession");
SqlSessionsqlSession=sqlSessionFactory.openSession();
try{
//獲取到指定mapper
PersonDaomapper=sqlSession.getMapper(PersonDao.class);
//調用指定mapper的方法,返回一個cursor
Cursorcursor=mapper.selectByCursor();
//查詢數據總量
Integertotal=mapper.queryCount();
//定義一個list,用來從cursor中讀取數據,每讀取夠1000條的時候,開始處理這批數據;
//當前批數據處理完之后,清空list,準備接收下一批次數據;直到大量的數據全部處理完;
ListpersonList=newArrayList<>();
inti=0;
if(cursor!=null){
for(Personperson:cursor){
if(personList.size()

應用場景

其實mybatis的流式查詢適用范圍很有限,這里舉個例子,假如有這樣一個需求 :有50萬員工的一年的工資數據明細,需要輸出一張公司支出工資的數據報表。

需求很簡單,估計有人是這樣想:這太簡單了,查詢出員工的工資數據明細,然后按照套上公式逐條計算出結果,然后匯總計算結果,插入到新的結果表里不就行了。事實上這件事絕對不簡單:

50萬的數據全部讀取到jvm的內存里得占用多大空間?

這么多對象的垃圾回收又需要多久?

這么多數據計算是高頻行為還是低步行為?

如果計算到某條員工的數據發生異常,已經計算好的數據要不要全部回滾?...

總之,直接取出50萬數據來計算,風險肯定不小。那怎么辦呢?

在實際的開發中,也經常遇到一些百十萬,說大不大,說小不小的數據報表處理,我的主要設計思路通常就是數據切隔+異步,具體怎么做呢?結合上面的例子,是這樣的:

1、按照月份、省份或者部門,對工資明細數據進行數據切隔分組;

2、把不同月份、省份、部門的工資數據包裝成多線程任務,放到線程池中去執行;

3、根據切隔的多線程任務數量,定義一個同步工具類CountDownLatch;

4、根據同步工具類CountDownLatch,來判斷所有的多線程任務是否全部執行完;等到所有的多線程任務全部執行完成后,再執行匯總的邏輯;

5、在多線程任務里,查詢具體月份、省份的員工工資數據明細的時候,如果數據量還是不少,就可以使用mybatis的流式查詢,分批獲取員工工資明細數據,進行當前批的計算、匯總,然后所有分批數據都計算完成后,再匯總所有分批數據;

注意事項

mybatis的流式查詢的本意,是避免大量數據的查詢而導致內存溢出,因此dao層查詢返回的是一個迭代器(Cursor),可以每次從迭代器中取出一條查詢結果,在實際業務開發過程中,即是根據實際的jvm內存大小,從迭代器中取出一定數量的數據后,再進行數據處理,待處理完之后,繼續取出一定數據再處理,以此類推直到全部數據處理完,這樣做的最大好處就是能夠降低內存使用和垃圾回收器的負擔,使數據處理的過程相對更加高效、可控,內存溢出的風險較小;

好處很明顯,缺點也很就明顯,處理的時間可能會變長,需要引入多線程異步操作,并且在迭代器遍歷和數據處理的過程中,數據庫連接不能斷開,即當前sqlSession要保持持續打開狀態,一量斷開,數據讀取就會中斷,所以關于這塊的處理,使用mybatis原生的sqlSession進行手動查詢、提交事務、回滾和關閉sqlSession最為穩妥、最簡單。





審核編輯:劉清

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

    關注

    0

    文章

    43

    瀏覽量

    4302
  • SpringBoot
    +關注

    關注

    0

    文章

    173

    瀏覽量

    167

原文標題:SpringBoot+Mybatis 如何實現流式查詢,你知道嗎?

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

收藏 人收藏

    評論

    相關推薦

    一文了解MyBatis查詢原理

    本文通過MyBatis一個低版本的bug(3.4.5之前的版本)入手,分析MyBatis的一次完整的查詢流程,從配置文件的解析到一個查詢的完整執行過程詳細解讀
    的頭像 發表于 10-10 11:42 ?1401次閱讀

    SpringBoot配置Mybatis的2個錯誤和修正

    SpringBoot】配置Mybatis錯誤
    發表于 04-19 10:31

    在pom.xml中增加mybatis-generator相關配置的步驟

    springboot配置mybatis-generator生成mybatis相關接口、xml文件、和實體類
    發表于 05-08 17:04

    基于SpringBoot mybatis方式的增刪改查實現

    SpringBoot mybatis方式實現增刪改查
    發表于 06-18 16:56

    數據庫整合Mybatis框架

    微服務 SpringBoot 20(九):整合Mybatis
    發表于 07-16 11:03

    mybatis的最簡兩種模式

    【本人禿頂程序員】springboot專輯:如何優雅的使用mybatis
    發表于 10-23 09:01

    MyBatis的整合

    SpringBoot-15-之整合MyBatis-注解篇+分頁
    發表于 10-28 08:09

    基于java springboot電影購票小程序源碼相關資料推薦

    后臺springboot mybatis 前端微信小程序電影院訂票系統用戶信息管理:用戶注冊后,可修改個人信息、登錄密碼等影片分類:對影片進行分類,按類型、國家區域分類,有篩選功能影片的信息:(影片
    發表于 12-30 06:14

    MyBatis實現原理

    本文主要詳細介紹了MyBatis實現原理。mybatis底層還是采用原生jdbc來對數據庫進行操作的,只是通過 SqlSessionFactory,SqlSession Executor
    的頭像 發表于 02-24 11:25 ?6461次閱讀
    <b class='flag-5'>MyBatis</b>的<b class='flag-5'>實現</b>原理

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

    作者丨捏造的信仰 segmentfault.com/a/1190000022478915 Part1基本概念 流式查詢指的是查詢成功后不是返回一個集合而是返回一個迭代器,應用每次從迭代器取一條
    的頭像 發表于 08-04 15:52 ?4159次閱讀

    Fluent Mybatis、原生MybatisMybatis Plus對比

    使用fluent mybatis可以不用寫具體的xml文件,通過java api可以構造出比較復雜的業務sql語句,做到代碼邏輯和sql邏輯的合一。不再需要在Dao中組裝查詢或更新操作,在xml或
    的頭像 發表于 09-15 15:41 ?1403次閱讀

    源碼學習之MyBatis的底層查詢原理

    本文通過MyBatis一個低版本的bug(3.4.5之前的版本)入手,分析MyBatis的一次完整的查詢流程,從配置文件的解析到一個查詢的完整執行過程詳細解讀
    的頭像 發表于 10-10 11:42 ?759次閱讀

    SpringBoot+ElasticSearch實現模糊查詢功能

    基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能
    的頭像 發表于 12-30 14:00 ?955次閱讀

    MyBatis-Plus為什么不支持聯表

    `的所有功能`MyBatis Plus Join`同樣擁有;框架的使用方式和`MyBatis Plus`一樣簡單,幾行代碼就能實現聯表查詢的功能
    的頭像 發表于 02-28 15:19 ?2404次閱讀
    <b class='flag-5'>MyBatis</b>-Plus為什么不支持聯表

    SpringBoot實現動態切換數據源

    最近在做業務需求時,需要從不同的數據庫中獲取數據然后寫入到當前數據庫中,因此涉及到切換數據源問題。本來想著使用Mybatis-plus中提供的動態數據源SpringBoot的starter:dynamic-datasource-spring-boot-starter來
    的頭像 發表于 12-08 10:53 ?982次閱讀
    <b class='flag-5'>SpringBoot</b><b class='flag-5'>實現</b>動態切換數據源