日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis-plus 大数据量数据流式查询通用接口

發(fā)布時(shí)間:2024/9/27 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis-plus 大数据量数据流式查询通用接口 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

          • 一、案例需求
          • 二、使用案例:
            • 2.1. 自定義查詢接口
            • 2.2. 邏輯處理類
            • 2.3. 調(diào)用案例
            • 2.4. 具體邏輯處理案例
          • 三、企業(yè)案例
            • 3.1. key名稱獲取
            • 3.2. 邏輯類測試
            • 3.3.最后一個(gè)批次處理方案
          • 四、 通用SQL預(yù)編譯處理
            • 4.1. 業(yè)務(wù)場景
            • 4.2. xml形式
            • 4.3. 注解形式
          • 五、企業(yè)案例
            • 5.1. sql語句
            • 5.2. 大數(shù)據(jù)流查詢接口
            • 5.3. 大數(shù)據(jù)查詢結(jié)果集處理抽象類
            • 5.4. 服務(wù)接口
            • 5.5. 服務(wù)接口實(shí)現(xiàn)類
            • 5.6. 前端控制器

聲明:
大數(shù)據(jù)流查詢解決查詢結(jié)果集過大的導(dǎo)致內(nèi)存溢出的問題。
針對(duì)查詢通用SQL與數(shù)據(jù)交互的次數(shù)加到數(shù)據(jù)庫壓力,要使用預(yù)編譯。

一、案例需求

查詢sys_user表中的所有數(shù)據(jù),數(shù)據(jù)庫中供3條數(shù)據(jù),在實(shí)際處理類中我設(shè)置了具體處理批次的數(shù)量為2條數(shù)據(jù)為一個(gè)批次,那么一個(gè)批次就只處理2條數(shù)據(jù),處理完成后,繼續(xù)處理下一個(gè)批次(2條數(shù)據(jù)),直至全部處理完成。

大病項(xiàng)目案例:數(shù)據(jù)庫查詢1次查詢數(shù)量為1000條,在實(shí)際的邏輯處理中,我設(shè)置了本次批次處理的數(shù)據(jù)數(shù)量為500條,那一個(gè)批次就只處理500條,處理完第1個(gè)批次500條后,在處理下一次批次的500條。

注:

  • 這個(gè)根據(jù)實(shí)際情況動(dòng)態(tài)設(shè)置
  • 項(xiàng)目中默認(rèn)1000條查詢數(shù)據(jù)庫一次(開發(fā)者可忽略)
  • 設(shè)計(jì)初衷:
    為了讓大家都按照規(guī)范去做,因此抽象此接口,具體實(shí)現(xiàn)類去繼承,獲取對(duì)應(yīng)的實(shí)體對(duì)象,然后一一獲取里面的對(duì)象。

    局限性:
    當(dāng)在一個(gè)類中獲取的對(duì)象不只是一個(gè),此抽象接口不能使用,需要單獨(dú)的在自己的實(shí)現(xiàn)類中,按照此方式手寫對(duì)用的mapper,待補(bǔ)充

    二、使用案例:
    2.1. 自定義查詢接口

    聲明接口作用:只是為了聽過一個(gè)接口供外部調(diào)用服務(wù)

    package com.gblfy.ly.service;public interface ISDQueryResulService {public void batchSDHandle(); }


    注:如果外部不需要調(diào)用,此接口可以省略,實(shí)現(xiàn)類可不實(shí)現(xiàn)此接口

    2.2. 邏輯處理類
    • 1>繼承extends SDQueryResultHandler重新handle方法,實(shí)現(xiàn)自己定義的接口
    • 2>注入SDQueryWrapper接口
      案例處理類路徑:
    com.gblfy.ly.service.impl. SDQueryResulServiceImpl

    如下圖所示:

    2.3. 調(diào)用案例
    1.自定義SQL語句 2.new 本身邏輯處理類 3.設(shè)置具體處理的批次數(shù)據(jù)數(shù)量 4.new 好的處理類變量名,放到此方法內(nèi)部 5.調(diào)用lastSDHandle方法注:具體使用請(qǐng)參考,案例代碼,已上傳gitlab倉庫

    2.4. 具體邏輯處理案例

    聲明:查詢批次的結(jié)果集最終返回的數(shù)據(jù)是一個(gè)list,大家只需要對(duì)list中的數(shù)據(jù)進(jìn)行循環(huán)遍歷,根據(jù)key獲取處理對(duì)應(yīng)的value即可。

    三、企業(yè)案例

    參數(shù)獲取方式:根據(jù)key獲取value,簡言之,查詢出來的數(shù)據(jù)放到了map中。

    3.1. key名稱獲取
  • 找到此類com.gblfy.ly.config. SDQueryResultHandler
  • 在31行和32行打上斷點(diǎn)
  • debug啟動(dòng)項(xiàng)目
  • url請(qǐng)求http://localhost/batchSDHandle
  • 進(jìn)項(xiàng)目,斷點(diǎn)跳到32行
  • 所有的key和value就都展示了出來
    如下圖所示:

    3.2. 邏輯類測試

    在com.gblfy.ly.service.impl. SDQueryResulServiceImpl類的35行打上斷點(diǎn),滿足一個(gè)批次的數(shù)量就會(huì)跳到handle此方法中


    注:數(shù)據(jù)庫一共5條數(shù)據(jù)。

    3.3.最后一個(gè)批次處理方案

    從開始到結(jié)束,按照批次依次執(zhí)行到最后一個(gè)批次,會(huì)自動(dòng)調(diào)用lastSDHandle方法,因此,我們只需要處理好handle()方法即可。
    最后,把獲取的數(shù)據(jù)進(jìn)行處理根據(jù)實(shí)際需求自行處理。

    四、 通用SQL預(yù)編譯處理
    4.1. 業(yè)務(wù)場景

    相同SQL和數(shù)據(jù)庫交互多次,請(qǐng)按照規(guī)范適應(yīng)預(yù)編譯處理。

    4.2. xml形式

    在xml文件中添加statementType="PREPARED"即屬性可

    4.3. 注解形式
    statementType = StatementType.PREPARED

    五、企業(yè)案例
    5.1. sql語句
    -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` bigint(20) NOT NULL COMMENT '主鍵ID',`name` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '姓名',`age` int(11) DEFAULT NULL COMMENT '年齡',`email` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '郵箱',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;-- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'Jone', '18', 'test1@baomidou.com'); INSERT INTO `user` VALUES ('2', 'Jack', '20', 'test2@baomidou.com'); INSERT INTO `user` VALUES ('3', 'Tom', '28', 'test3@baomidou.com'); INSERT INTO `user` VALUES ('4', 'Sandy', '21', 'test4@baomidou.com'); INSERT INTO `user` VALUES ('5', 'Billie', '24', 'test5@baomidou.com');
    5.2. 大數(shù)據(jù)流查詢接口
    package com.gblfy.ly.mapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.gblfy.ly.entity.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.ResultSetType; import org.apache.ibatis.mapping.StatementType; import org.apache.ibatis.session.ResultHandler;import java.util.Map;/*** 處理流數(shù)據(jù)的公用接口** @author gblfy* @date 2020-11-18*/ @Mapper public interface SDQueryWrapper {/*** ResultSetType.FORWARD_ONLY 表示游標(biāo)只向前滾動(dòng)* fetchSize 每次查詢數(shù)量* @ResultTyp 定義返回的對(duì)象類型** @param sql SQL語句* @param handler 返回處理數(shù)據(jù)對(duì)象*/@Select("${sql}")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)@ResultType(Map.class)void streamDataDynamicHandle(@Param("sql") String sql, ResultHandler<Map> handler);@Select("${sql}")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 2)@ResultType(User.class)void dynamicSelectLargeData1(@Param("sql") String sql, ResultHandler<User> handler);@Select("select * from user t ${ew.customSqlSegment}")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000,statementType = StatementType.PREPARED)@ResultType(User.class)void getOrgWithBigData(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper, ResultHandler<User> handler); }
    5.3. 大數(shù)據(jù)查詢結(jié)果集處理抽象類
    package com.gblfy.ly.config;import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.util.ArrayList; import java.util.List; import java.util.Map;/*** 大數(shù)據(jù)查詢結(jié)果集處理抽象類** @author gblfy* @date 2020-11-18*/ public abstract class SDQueryResultHandler implements ResultHandler<Map> {private final static Logger logger = LoggerFactory.getLogger(SDQueryResultHandler.class);// 這是每一個(gè)批處理查詢的數(shù)量public int batchSize = 1000;//初始值public int size=0;// 存儲(chǔ)每批數(shù)據(jù)的臨時(shí)容器public List<Map> list = new ArrayList<Map>();public void handleResult(ResultContext<? extends Map> resultContext) {// 這里獲取流式查詢每次返回的單條結(jié)果Map map = resultContext.getResultObject();list.add(map);size++;if (size == batchSize) {logger.info("本批次處理數(shù)據(jù)量 :{}",size );handle();}}// 1.這個(gè)方需要子類重寫此接口,處理具體業(yè)務(wù)邏輯public abstract void handle();//處理最后一批不到 batchSize(查詢?cè)O(shè)定的閥值)的數(shù)據(jù)public void lastSDHandle() {logger.info("最后批次處理數(shù)據(jù)量 :{}",size );handle();}public void setBatchSize(int batchSize) {this.batchSize = batchSize;} }
    5.4. 服務(wù)接口
    package com.gblfy.ly.service;public interface ISDQueryResulService {public void batchSDHandle(); }
    5.5. 服務(wù)接口實(shí)現(xiàn)類
    package com.gblfy.ly.service.impl;import com.gblfy.ly.config.SDQueryResultHandler; import com.gblfy.ly.mapper.SDQueryWrapper; import com.gblfy.ly.service.ISDQueryResulService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service public class SDQueryResulServiceImpl extends SDQueryResultHandler implements ISDQueryResulService {private final static Logger logger = LoggerFactory.getLogger(SDQueryResulServiceImpl.class);@Resourceprivate SDQueryWrapper sdQueryWrapper;@Overridepublic void batchSDHandle() {String sql = "select * from user";SDQueryResulServiceImpl sdQueryResulService = new SDQueryResulServiceImpl();sdQueryResulService.setBatchSize(2);//批量處理數(shù)據(jù)量 根據(jù)實(shí)際情況設(shè)置//1.按批次處理查詢結(jié)果集數(shù)據(jù)sdQueryWrapper.streamDataDynamicHandle(sql,sdQueryResulService);//2.處理最后一個(gè)批次的查詢結(jié)果數(shù)據(jù)sdQueryResulService.lastSDHandle();}// 在這里可以對(duì)你獲取到的批量結(jié)果數(shù)據(jù)進(jìn)行需要的業(yè)務(wù)處理@Overridepublic void handle() {try {logger.info("---------------------:{}",list.size());//list 批量查詢結(jié)果集,對(duì)此list進(jìn)行業(yè)務(wù)處理for (int i = 0; i < list.size(); i++) {logger.info("---------------------:{}",list.get(i).get("name"));}} finally {// 處理完每批數(shù)據(jù)后后將臨時(shí)清空size = 0;list.clear();}} }
    5.6. 前端控制器
    package com.gblfy.ly.controller;import com.gblfy.ly.service.ISDQueryResulService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;@RestController public class SDQueryResultController {@Autowiredprivate ISDQueryResulService isdQueryResulService;@GetMapping("/batchSDHandle")public void batchSDHandle() {isdQueryResulService.batchSDHandle();} }

    總結(jié)

    以上是生活随笔為你收集整理的Mybatis-plus 大数据量数据流式查询通用接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。