XhHQL大批量数据处理过程的方法

举报
星汉网络 发表于 2022/05/02 21:17:46 2022/05/02
【摘要】 在进行大量数据运算的过程中,会遇到性能瓶颈,同时还会引发内存溢出等问题。主要体现在,百万级的数据库数据的处理上。要充分利用如下的方法,进行分组处理。同时还要控制提交批次,避免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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。