Mybatis集成MySQL使用游标查询处理大批量数据

发布时间:2024年01月18日

背景

基于数据的时间范围查询,给符合条件的用户推送积分即将到期的提醒。

初期用户量小使用最普通简单的分页查询扫描数据处理数据没问题。随着用户量的上升表数据已经上千万,每天扫描处理的数量也超百万,limit分页出现了慢sql,任务执行时间也达不到预期了。

上述方案出现瓶颈后考虑放弃limit方案,使用游标的方式进行全量数据的获取,这样一来SQL执行快任务执行也快。

MySQL游标查询

useCursorFetch

使用游标查询时,,必须在jdbc url上设置连接属性参数useCursorFetch=true

FetchSize?

在设置了useCursorFetch=true后,需要在SQL中指定fetchSize,即一次获取的数据量。

如果不设置fetchSize参数,则执行时仍然是全量返回,可能会出现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做大量数据查询后写入文件的代码示例。

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是如何实现基于Cursor查询的

com.mysql.cj.jdbc.result.ResultSetImpl

ResultSetImpl 是mybatis中实现游标查询结果解析的类。

文章来源:https://blog.csdn.net/qq_29569183/article/details/134450570
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。