我是靠谱客的博主 酷酷纸鹤,最近开发中收集的这篇文章主要介绍记一次优化JPA批量存储数据,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

记一次优化JPA批量存储数据

    • 写在前面
    • 一、优化细节
    • 二、批量 insert 数据时,应注意的

写在前面

JPA中的批量存储方案,Save( ),或者saveAll( ),

一、优化细节

其实数据不大,excel 导入 500条数据,用了 40s,可能的原因

  • excel解析速度
  • 集合操作(几种for循环的不同)
  • JPA的保存操作,save()和saveAll()

其实最后,试了很多次,这么都不是主要原因,而是SpringSecurity中一个对象

    // 这里密码部分若是放到循环里面,会大大消耗执行时间
        String encode = passwordEncoder.encode(Constants.USER_DEFAULT_PD);

        usersFromExcel.forEach(user -> {
            user.setPassword(encode);
            user.setDepartmentId(departmentNames.get(user.getDepartmentName().trim()));

            user.setCreateBy(currentUserLogin);
            user.setUpdateBy(currentUserLogin);
            user.setCreateTime(now);
            user.setUpdateTime(now);
            UserInfo saveUser = userRepository.save(user);

            UserRole userRole = new UserRole(saveUser.getUserId(), defaultRoleId);
            userRoleRepository.save(userRole);
        });

二、批量 insert 数据时,应注意的

  • 尽量使用saveAll(),有时候并不是主要原因,甚至两者差不多,两者在保存时,其实都对数据验证了,其实也浪费了没必要的步骤,
  • Mysql服务端的缓存配置
  • 客户端的连接配置
  • 构造初始化对象,这里可能是你并没有很好的初始化对象,占用太多时间构造数据(save之前)
  • save(),或者SaveAll(),或者如下代码,分批次批处理
  • 多线程异步操作,分隔 task,以及单个失败时,处理机制

分批次批处理,处理方案

//     公共方法抽取
    private void saveUsers(LocalDateTime now, String currentUserLogin, List<UserInfo> usersFromExcel,
            Map<String, Long> departmentNames,Long defaultRoleId) {

        usersFromExcel.forEach(user -> {
            user.setPassword(passwordEncoder.encode(Constants.USER_DEFAULT_PD));
            user.setDepartmentId(departmentNames.get(user.getDepartmentName().trim()));

            user.setCreateBy(currentUserLogin);
            user.setUpdateBy(currentUserLogin);
            user.setCreateTime(now);
            user.setUpdateTime(now);
        });


        // 批量保存
        List<UserInfo> userInfos = userRepository.saveAll(usersFromExcel);
//        this.addListModelParams(usersFromExcel);

//        List<UserRole> collect = usersFromExcel.stream().map(e -> new UserRole(e.getUserId(), defaultRoleId)).collect(Collectors.toList());
//
//        userRoleRepository.saveAll(collect);
    }

    public void addListModelParams(List<UserInfo> list) {
        int listsize = list.size();
        if (listsize == 0) {
            throw new RuntimeException("集合为空!") ;
        } else {

            //批量存储的集合
            List<UserInfo> data = new ArrayList<UserInfo>();

            //批量存储
            for (UserInfo s : list) {
                // 分 6 次批量存储
                if(data.size() == listsize/5) {
                    userRepository.saveAll(data);
                    data.clear();
                }
                data.add(s);
            }
            //将剩下的数据也导入
            if(!data.isEmpty()) {
                userRepository.saveAll(data);
            }
        }
    }

最后

以上就是酷酷纸鹤为你收集整理的记一次优化JPA批量存储数据的全部内容,希望文章能够帮你解决记一次优化JPA批量存储数据所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部