XhHQL大批量数据处理过程的方法
【摘要】 在进行大量数据运算的过程中,会遇到性能瓶颈,同时还会引发内存溢出等问题。主要体现在,百万级的数据库数据的处理上。要充分利用如下的方法,进行分组处理。同时还要控制提交批次,避免Hibernate的数据提交方式。1、数组列表类型数据,使用 BatcherList 方法public class BatcherList<T>{ private final List<T> list = new ...
在进行大量数据运算的过程中,会遇到性能瓶颈,同时还会引发内存溢出等问题。主要体现在,百万级的数据库数据的处理上。要充分利用如下的方法,进行分组处理。同时还要控制提交批次,避免Hibernate的数据提交方式。
1、数组列表类型数据,使用 BatcherList 方法
public class BatcherList<T>
{
private final List<T> list = new ArrayList<>();
@Setter
private int size = 1000;
@Setter
private Consumer<List<T>> deal;
/**
* 向队列中插入数据,当到达指定长度后,进行处理
* @param bean
*/
public void push(T bean)
{
if (list.size() == size) doDeal();
list.add(bean);
}
/**
* 执行数据处理的方法
*/
public void doDeal()
{
if (list.isEmpty()) return;
deal.accept(list);
list.clear();
}
}
2、如果使用Map的场景,要使用 BatcherMapper 类处理
public class BatcherMapper<K, T>
{
private final Map<K, T> map = new HashMap<>();
@Setter
private int size = 1000;
@Setter
private Consumer<Map<K, T>> deal;
/**
* 没有到达数据的结尾位置,控制循环的结束
*/
@Getter
private boolean notEnd = false;
/**
* 向队列中插入数据,当到达指定长度后,进行处理
* @param bean
* @param field
*/
public void push(T bean, Function<T, K> field)
{
notEnd = true;
K key = field.apply(bean);
if (map.size() == size) doDeal();
map.put(key, bean);
}
/**
* 执行数据处理的方法
*/
public void doDeal()
{
if (map.isEmpty()) return;
deal.accept(map);
map.clear();
}
}
3、在调用的位置,进行初始化处理。示例如下,注意其中Map的初始化和批处理的执行。
private boolean doInsertData() {
XhHQL hql = XhHQL.from(BasicFinancialStatisticsBean.class).no("update");
return transaction(session -> {
BatcherMapper<String, BasicFinancialStatisticsBean> batcher = new BatcherMapper<>();
batcher.setDeal(map -> {
//执行数据处理
this.doBatchData(map);
session.flush();
session.clear();
});
session.createQuery(hql.build()).setMaxResults(MAX_LENGTH).stream().forEach(
//插入待处理的数据
item -> batcher.push((BasicFinancialStatisticsBean) item,
BasicFinancialStatisticsBean::getEasCode));
batcher.doDeal();
return batcher.isNotEnd();
});
}
4、上面方法中,特别注意 transaction 的使用。在一次事务过程中,控制了数据的处理和提交。doBatchData 方法,是具体的业务实现。在下方的方法:
.setMaxResults(MAX_LENGTH)
主要用来设置,本次数据处理的长度。根据服务器的性能设置,一般设置为10000左右。
5、最外层,可以使用while循环,完成整个数据处理过程,如下:
while (doInsertData());
这样,通过整个循环体,可以完成百万级大数据量的数据批次处理。不再对内存和CPU造成过大压力。执行效率方法,从前期测试的结论来看,还是比较可观的。主要取决于 业务处理过程。尽量降低 关联表的查询,和循环内的 多次数据库交互。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)