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


猜你喜欢
- 介绍前面一章说了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostPr
- 用java实现循环队列的方法:1、添加一个属性size用来记录眼下的元素个数。目的是当head=rear的时候。通过size=0还是size
- Java并发包的locks包里的锁基本上已经介绍得差不多了,ReentrantLock重入锁是个关键,在清楚的了解了同步器AQS的运行机制后
- 预览图一、xml布局<?xml version="1.0" encoding="utf-8"?
- 如何:对 Windows 窗体控件进行线程安全调用访问 Windows 窗体控件本质上不是线程安全的。 如果有两个或多个线程操作某一控件的状
- 中国科学院开源协会镜像站地址:IPV4/IPV6: http://mirrors.opencas.cn 端口:80IPV4/IPV6: ht
- MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoD
- 概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:1、若它的左子树不为空,则左子树上所有节点的值都小于根结点的值。
- 引言最近,各大平台都新增了评论区显示发言者ip归属地的功能,例如哔哩哔哩,微博,知乎等等。Java 中是如何获取 IP&
- 本文实例为大家分享了android自定义imageview实现圆角图片的具体代码,供大家参考,具体内容如下自定义图片的属性,对图片进行圆角切
- 本文讲述绘制Android自定义各种图形效果,为自定义控件的入门篇 相关视频链接: Android自定义控件系列 http://edu.cs
- 通常情况下,Android实现自定义控件无非三种方式。Ⅰ、继承现有控件,对其控件的功能进行拓展。Ⅱ、将现有控件进行组合,实现功能更加强大控件
- 最近有一款2048的游戏非常火,本文将来介绍一下使用OGEngine游戏引擎开发游戏2048。OGEngine引擎是开源的,我们很容易找到,
- 一、什么是JWTJSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案。现在的项目开发一般都是前端端分离,这就涉及到
- Spring * 监测每个Controller或方法的执行时长首先写一个类(TestInterceptor)让他继承HandlerInter
- 本文实例为大家分享了Unity3D仿写Button面板事件绑定功能的具体代码,供大家参考,具体内容如下最近在做一个情节引导得项目。其中一个需
- 首先说的是LinearLayout布局下的居中一般是这样的:(注意:android:layout_width="fill_pare
- Android的Camera相关应用开发中,有一个必须搞清楚的知识点,就是Camera的预览方向和拍照方向图像的Sensor方向:手机Cam
- 建库建表DROP DATABASE IF EXISTS mp;CREATE DATABASE mp DEFAULT CHARACTER SE
- 前言《黄金矿工》游戏是一个经典的抓金子小游戏,它可以锻炼人的反应能力。。该游戏中,可以通过“挖矿”获