Mybatis Plus中的流式查询案例
作者:Jon 发布时间:2023-08-18 16:35:13
标签:Mybatis,Plus,流式查询
Mybatis Plus流式查询
mybatis plus 中自定义如下接口,就可以实现流式查询,mybatis 中同样适用。
@Select("select * from t_xxx t ${ew.customSqlSegment}")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(ClearReconDiffAbnormalDO.class)
void listByStream(@Param(Constants.WRAPPER) Wrapper<Model> wrapper, ResultHandler<Model> resultHandler);
通用流式查询
编写流式查询的方法:
public class FetchByStream extends AbstractMethod {
private static final String METHOD = "fetchByStream";
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sqlFormat = "<script>\nSELECT %s FROM %s %s %s\n</script>";
String sql = String.format(sqlFormat, sqlSelectColumns(tableInfo, true),
tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
String statementName = mapperClass.getName() + DOT + METHOD;
if (configuration.hasStatement(statementName, false)) {
logger.warn(LEFT_SQ_BRACKET + statementName + "] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [" + getClass() + RIGHT_SQ_BRACKET);
return null;
}
/* 缓存逻辑处理 */
return builderAssistant.addMappedStatement(METHOD, sqlSource, StatementType.PREPARED, SqlCommandType.SELECT,
Integer.MIN_VALUE, null, null, null, null, modelClass,
ResultSetType.FORWARD_ONLY, true, true, false, null, null, null,
configuration.getDatabaseId(), languageDriver, null);
}
}
然后再注入通用方法,在Mapper 写入下方的 method 即可使用。
void fetchByStream(@Param(Constants.WRAPPER) Wrapper<T> wrapper, ResultHandler<T> handler);
Mybatis Plus大数据量流式查询
一、在需要使用流式查询的mapper文件中,定义流式查询方法
package com.unionpay.dao.db2;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.unionpay.entity.TblMallOrder;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.ResultSetType;
import org.apache.ibatis.session.ResultHandler;
/**
* (TblMallOrder)表数据库访问层
*
* @author liudong
* @since 2020-09-15 17:07:13
*/
@Mapper
public interface TblMallOrderDao extends BaseMapper<TblMallOrder> {
@Select("${sql}")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(TblMallOrder.class)
void dynamicSelectLargeData1(@Param("sql") String sql, ResultHandler<TblMallOrder> handler);
@Select("${sql}")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(Map.class)
void dynamicSelectLargeData2(@Param("sql") String sql, ResultHandler<Map> handler);
}
二、使用示例
@RestController
public class TestSearchLargeData {
// 这是每批处理的大小
private final static int BATCH_SIZE = 1000;
private int size;
// 存储每批数据的临时容器
private List<TblMallOrder> mallOrders;
@Autowired
private TblMallOrderDao tblMallOrderDao;
@GetMapping("/getLargeData1")
public void getLargeData1() {
String sql = "select * from t_mall_order";
tblMallOrderDao.dynamicSelectLargeData1(sql, new ResultHandler<TblMallOrder>() {
@Override
public void handleResult(ResultContext<? extends TblMallOrder> resultContext) {
TblMallOrder tblMallOrder = resultContext.getResultObject();
System.out.println(tblMallOrder);
}
});
}
@GetMapping("/getLargeData2")
public void getLargeData2() {
String sql = "select * from t_mall_order";
tblMallOrderDao.dynamicSelectLargeData1(sql, new ResultHandler<TblMallOrder>() {
@Override
public void handleResult(ResultContext<? extends TblMallOrder> resultContext) {
TblMallOrder tblMallOrder = resultContext.getResultObject();
System.out.println(tblMallOrder);
// 你可以看自己的项目需要分批进行处理或者单个处理,这里以分批处理为例
mallOrders.add(tblMallOrder);
size++;
if (size == BATCH_SIZE) {
handle();
}
}
});
//用来完成最后一批数据处理
handle();
}
/**
* 数据处理
*/
private void handle(){
try{
// 在这里可以对你获取到的批量结果数据进行需要的业务处理
}catch (Exception e){
e.printStackTrace();
}finally {
// 处理完每批数据后后将临时清空
size = 0;
mallOrders.clear();
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
来源:https://blog.csdn.net/JonKee/article/details/119935265
0
投稿
猜你喜欢
- 在android开发中,有时候我们想获取手机的一些硬件信息,比如android手机的总内存和可用内存大小。这个该如何实现呢?通过读取文件&q
- 1 配置文件的方法我们编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量
- 这是Hadoop学习全程记录第1篇,在这篇里我将介绍一下如何在Linux下安装Hadoop1.x。先说明一下我的开发环境:虚拟机:VMwar
- (注意:本文基于JDK1.8) 前言包括迭代器中的remove()方法,以及删除单个元素、删除多个元素、删除所有元素、删除不包含的
- Java 8支持动态语言,看到了很酷的Lambda表达式,对一直以静态类型语言自居的Java,让人看到了Java虚拟机可以支持动态语言的目标
- 1.获取签名与模板进入阿里云平台,进入短信服务模块,在以下位置添加签名和模板(格式一定按照要求填写 审批的比较严格)2.编写模板与签名的枚举
- Springboot自带定时任务实现动态配置Cron参数同学们,我今天分享一下SpringBoot动态配置Cron参数。场景是这样子的:后台
- 一、介绍Properties文件在Java中主要为配置文件,文件类型为:.properties,格式为文本文件,内容格式为"键=值
- 今天在码代码的时候突然想到这个问题,觉得有点困惑。在网上也翻阅不少帖子其中有一个帖子给了我一个思路,其实也是解释了基础概念。概念一:try
- 接触FFmpeg有一段时间了,它是音视频开发的开源库,几乎其他所有播放器、直播平台都基于FFmpeg进行二次开发。本篇文章来总结下采用FFm
- 用户在注册网站信息的时候基本上都要数据验证码验证。那么图片验证码功能该如何实现呢?大概步骤是:1.在内存中创建缓存图片2.设置背景色3.画边
- 一,网络编程中两个主要的问题一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。在TCP/IP协议中I
- @SpringBootApplication的使用1. Spring Boot 的核心1.1. 入口类和 @SpringBootApplic
- 你是否受够了每次修改静态文件都要重启服务器?有时候在一些公司前后端的职责没有那么的明确,往往后台人员也要去写一些页面,像jsp页面,或者其他
- 简单理解泛型泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量
- 本文实例为大家分享了android TextView跑马灯效果的具体代码,供大家参考,具体内容如下一、要点设置四个属性android:sin
- 昨天实现一个功能,根据文章的id或者别名查找文章。起初采用mybatis的Example进行查询,对参数artName进行判断,如果是纯数字
- 前置说明:这里的代码演示都是在UserController类里面使用UserService类,然后通过启动类调用UserController
- 测试参数设置:1、循环调用new A()实现堆溢出,java.lang.OutOfMemoryError: Java heap space,
- 概念尽量使用合成/聚合,而不是使用继承实现复用。所谓的合成/聚合是指一个对象里持有另外一个类的对象,通过调用这些对象的方法得到复用已有功能的