最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis集成MySQL使用游標(biāo)查詢處理大批量數(shù)據(jù)方式

 更新時間:2024年01月27日 09:50:12   作者:WannaRunning  
這篇文章主要介紹了Mybatis集成MySQL使用游標(biāo)查詢處理大批量數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

背景

基于數(shù)據(jù)的時間范圍查詢,給符合條件的用戶推送積分即將到期的提醒。

初期用戶量小使用最普通簡單的分頁查詢掃描數(shù)據(jù)處理數(shù)據(jù)沒問題。隨著用戶量的上升表數(shù)據(jù)已經(jīng)上千萬,每天掃描處理的數(shù)量也超百萬,limit分頁出現(xiàn)了慢sql,任務(wù)執(zhí)行時間也達(dá)不到預(yù)期了。

上述方案出現(xiàn)瓶頸后考慮放棄limit方案,使用游標(biāo)的方式進(jìn)行全量數(shù)據(jù)的獲取,這樣一來SQL執(zhí)行快任務(wù)執(zhí)行也快。

MySQL游標(biāo)查詢

useCursorFetch

使用游標(biāo)查詢時,必須在jdbc url上設(shè)置連接屬性參數(shù)useCursorFetch=true

FetchSize

在設(shè)置了useCursorFetch=true后,需要在SQL中指定fetchSize,即一次獲取的數(shù)據(jù)量。

如果不設(shè)置fetchSize參數(shù),則執(zhí)行時仍然是全量返回,可能會出現(xiàn)OOM。

Mybatis集成Cursor查詢

mapper接口方法返回值聲明為Cursor類型,下面是SQL和Mapper的示例。

Cursor<Long> selectExpireCouponMember(@Param("endTime") String endTime);
 
 
<select id="selectExpireCouponMember" resultType="java.lang.Long" fetchSize="5000">
	select
		distinct member_id
	from t_dj_coupon
	where
	   end_time > end_time < #{endStartTime} and end_time < #{endTime}
</select>

下面是基于上面的SQL做大量數(shù)據(jù)查詢后寫入文件的代碼示例。

String fileName = DateFormatUtils.format(System.currentTimeMillis(), DateUtils.PATTERN_YYYY_MM_DD) + "_status_push_member.txt";
File file = new File(fileName);
file.createNewFile();
 
fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
	DjCouponMapper mapper = sqlSession.getMapper(DjCouponMapper.class);
	try (Cursor<Long> cursor = mapper.selectStartCouponMember(startDate, startDateEnd, BrandContextHolder.getBrandMdCode())) {
		Iterator<Long> iterator = cursor.iterator();
		Set<Long> couponMemberSet = new HashSet<>(pageSize.intValue());
		while (iterator.hasNext()) {
			couponMemberSet.add(iterator.next());
			writeNum++;
			if (couponMemberSet.size() >= pageSize) {
				bufferedWriter.write(couponMemberSet.toString());
				bufferedWriter.newLine();
				bufferedWriter.flush();
				writeLine++;
				couponMemberSet.clear();
			}
		
		}
		if (CollectionUtils.isNotEmpty(couponMemberSet)) {
			bufferedWriter.write(couponMemberSet.toString());
			bufferedWriter.newLine();
			bufferedWriter.flush();
			writeLine++;
		}
	}
}

Mybatis是如何實現(xiàn)基于Cursor查詢的

com.mysql.cj.jdbc.result.ResultSetImpl實現(xiàn)類

ResultSetImpl 是mybatis中實現(xiàn)游標(biāo)查詢結(jié)果解析的類。

這個實現(xiàn)類的next方法中調(diào)用了ResultsetRows接口的next方法。

ResultsetRows接口

ResultsetRows接口有ResultsetRowsCursor,ResultsetRowsStatic,ResultsetRowsStreaming三個實現(xiàn)類。

本文寫的游標(biāo)查詢的場景,使用的是ResultsetRowsCursor這個實現(xiàn)類。

詳細(xì)看下ResultsetRowsCursor這個實現(xiàn)類,主要是實現(xiàn)了Iterator的hasNext和next方法,這也是使用Cursor獲取數(shù)據(jù)需要的兩個方法。

下面是hasnext方法的邏輯,根據(jù)下次要獲取的游標(biāo)索引和當(dāng)前本地數(shù)據(jù)集計算返回是否還有后續(xù)數(shù)據(jù)可以獲取。

下面是next方法的邏輯,先執(zhí)行一下hasnext的邏輯判斷,再取值

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

石首市| 蓝山县| 惠州市| 南开区| 恩平市| 崇礼县| 微博| 北碚区| 黑龙江省| 林甸县| 新田县| 湘潭县| 县级市| 大厂| 赞皇县| 宜丰县| 平乡县| 枣强县| 叶城县| 房山区| 和田市| 贡觉县| 普兰县| 攀枝花市| 寻乌县| 观塘区| 乳山市| 凤阳县| 延吉市| 奉节县| 无极县| 兴城市| 会理县| 图片| 普定县| 理塘县| 宁乡县| 博白县| 嘉善县| 胶南市| 桐城市|