当前位置:网站首页>分批数据遍历的优化
分批数据遍历的优化
2022-07-29 17:23:00 【逆水行舟没有退路】
文章目录
前言
有时候,我们进行大数据批量遍历检查等操作,常规的操作,我们通常需要手动实现分页形式的遍历,例如需要从数据库读取100万条记录,通常我们可能需要手动分批5000条一次进行数据读取和操作。
如何简化代码的书写,进行大数据的批量遍历。
传统的大批量的数据遍历的写法(仅作示例)
/** * 1. 计算总页数 */
String sql="select count(1) ct from xxxx";
//通过数据库,计算总页数
int pageSize=10;
/** * 2. 按页执行遍历 */
for(int i=0;i<pageSize;i++){
/** * 3. 单页查询遍历 */
String sql2="select * from xxxx limit "+(i*5000)+","+(i+1)*5000;
List list=new ArrayList<>(); //执行sql2获取数据
for(Object obj:list){
System.out.println(obj);
}
}
上面的代码大致是我们遍历数据库的操作,逻辑清晰,但是代码比较繁琐和冗长。
如何简化这种逻辑结构,实现更清晰简单的数据遍历。
我们通过自定义的遍历器,实现数据的遍历,简化遍历层级,实现一级遍历,不关注数据的分页拆分。
如何实现批量数据遍历
- 定义抽象的集合遍历器
package com.lengcz.tools;
import java.util.List;
/** * 数据遍历器 * * @author leng * @param <T> * */
public abstract class AbstractListIterator<T> {
private List<T> data;
private long index = -1;
/** * 分页数量 */
private int pageSize = 5000;
private int currentIndex = -1;
private long totalSize = 0;
private long pageNo = 0;
public AbstractListIterator() {
}
public AbstractListIterator(int pageSize) {
if (pageSize < 1) {
throw new IllegalArgumentException("pageSize must be greater than 0.");
}
this.pageSize = pageSize;
}
/** * 取得元素 * * @return */
public T get() {
return data.get(currentIndex);
}
/** * 去到下一个元素 * * @return */
public boolean toNext() {
boolean flag = true; // 角标是否+1
try {
if ((index + 1) >= totalSize) {
// 总数为0或者totalSize&pageSize等于0,则继续下一页的数据
if (totalSize == 0 || ((totalSize % pageSize) == 0)) {
// 数量为0或者总数整除pageSize,则翻下一页
List<T> tempData = getPage(totalSize, totalSize + pageSize);
if (null == tempData || tempData.size() == 0) {
flag = false;
return false;
}
pageNo++;
this.data = tempData;
totalSize = totalSize + tempData.size();
currentIndex = -1;
// System.out.println(data);
} else if (totalSize == (index + 1)) {
// 表示最后一个了
flag = false;
return false;
}
}
} finally {
if (flag) {
// 表示下标能移动
currentIndex++;// 当前下标
index++;// 总下标
}
}
return flag;
}
/** * 分页获取 * * @param fromIndex * 包含 * @param toIndex * 不包含 * @return */
public abstract List<T> getPage(long fromIndex, long toIndex);
/** * 测试输出 */
public void print() {
System.out.println("===========AbstractListIterator arguments==============");// 总指针下标
System.out.println("index:" + index);// 总指针下标
System.out.println("pageSize:" + pageSize);// 单页数
System.out.println("pageNo:" + pageNo);// 第x页
System.out.println("currentPageSize:" + (null != data ? data.size() : 0));// 当前页数据量
System.out.println("currentIndex:" + currentIndex);// 当前集合的真实下标
System.out.println("totalSize:" + totalSize);// 总数
System.out.println("data:" + data); // 数据集合
}
}
- 测试或者使用抽象遍历器,根据AbstractListIterator,我们只需要集成该类,实现getPage方法即可使用该类进行遍历,而不需要关心数据遍历
package com.lengcz.tools;
import java.util.ArrayList;
import java.util.List;
public class AbstractListIteratorTest {
/** * 构造的需要遍历的数据a0到a23 */
public static List<String> list=new ArrayList<>();
static{
for(int i=0;i<24;i++){
list.add("a"+i);
}
}
public static void main(String[] args) {
AbstractListIterator<String> it=new AbstractListIterator<String>(10) {
@Override
public List<String> getPage(long fromIndex, long toIndex) {
if(fromIndex>list.size()){
fromIndex=list.size();
}
if(toIndex>list.size()){
toIndex=list.size();
}
return list.subList((int)fromIndex,(int) toIndex);
}
};
System.out.println("=====进行数据遍历=====");
while(it.toNext()){
System.out.println(it.get());
}
it.print();//调试打印参数内容
}
}
注意: 这里pageSize为10是方便测试,建议设置为单词批量的处理值,例如5000
打印日志输出,只是通过简单的whie循环,即可实现全数据的遍历。

总结
实现分批数据遍历的方法分两步
(1) 继承AbstractListIterator类,实现getPage方法
(2) 使用where循环遍历
while(it.toNext()){
//切换到下一条
System.out.println(it.get()); //获取数据
}
边栏推荐
猜你喜欢

lua-调试技巧

Swagger

地球超2亿蛋白质结构全预测,AlphaFold引爆「蛋白质全宇宙」

"Record" MMDetection Introduction

UNIX Environment Advanced Programming Chapter 3

This week's investment report: CeFi accumulates venture capital attraction

不同的 DAO 对世界带来的改变

观点:灵魂绑定NFT和去中心化社会

生产计划体系完整解决方案(1) - 复杂大规模问题的分阶段规划

Interviewer: How does MySQL tune SQL statements based on execution plans?
随机推荐
"Hardcore" labelme shows the label in the picture
Pagination with LIMIT
固件、驱动、软件的区别
Google Earth Engine APP——一键在线查看全球1984-至今年的影像同时加载一个影像分析
Domino服务器SSL证书安装指南
一个redis工具类解决缓存击穿,缓存穿透
DTSE Tech Talk丨第2期:解读云原生技术下,SaaS应用技术架构设计
Thread Dump分析方法
【WSL】wsl pip NewConnectionError
「硬核」labelme 图片中显示标签
针不戳!腾讯云架构师出品的《MySQL性能优化和高可用架构实践》
巴比特 | 元宇宙每日必读:连续七个季度出现亏损,Meta元宇宙部门Q2亏损28 亿美元,扎克伯格称这种情况可能会持续数年...
数学分析_证明_两个重要极限(同济版本)
leetcode53 -- 最大数组和
In the Chinese ToB market, it is too difficult to choose the right supplier
对话加拿大工程院于非院士:寻找 AI 领域的「香农定理」
传统渲染农场和云渲染农场选择哪个好?
Interface Project 02 Documentation: Jmeter Interface Testing and Performance Testing
地球超2亿蛋白质结构全预测,AlphaFold引爆「蛋白质全宇宙」
HER2-2-ME-BSANPs单抗特异性的2-甲氧基雌二醇白蛋白纳米粒的研究与制备