Java后端爱上SpringBoot 第五节:SpringBoot 批量提交
2018-12-31 16:10
483 查看
Java后端爱上SpringBoot 第五节:Spring-Data-JPA批量提交
PS:因为项目中用到了批量提交,因此来记录一下几种批量提交的方式。
Spring-Data-JPA批量提交
随便找一个实体的Repository来进行提交:
贴一下单元测试类:
@Test public void test9() { Optional<SysUser> optional = iSysUserRepository.findById("2c987c3167a23e990167a240e0c80008"); Long startTime=System.currentTimeMillis(); if (optional.isPresent()) { List<SysUser> sysUsers = new ArrayList<>(10000); // 提交1W個 for (int i = 0; i < 10000; i++) { SysUser sysUser = new SysUser(); sysUser=optional.get(); sysUser.setId(String.valueOf(i)); sysUsers.add(sysUser); } iSysUserRepository.saveAll(sysUsers); } Long endTime=System.currentTimeMillis(); System.out.println("耗时:"+(endTime-startTime)+"ms"); }
提交时间为:
又测了一次:
好慢啊!看一下saveAll()这个方法的源码。
于是我们找到了org.springframework.data.jpa.repository.support.SimpleJpaRepository<T, ID>的saveAll方法。
@Transactional public <S extends T> List<S> saveAll(Iterable<S> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); List<S> result = new ArrayList<S>(); for (S entity : entities) { result.add(save(entity)); } return result; }
再去看一下save方法:
@Transactional public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } }
发现每提交一个实体都会去 isNew 一下,去数据库查询这个实体是不是新的,如果是新的则进行提交,否则则进行update,于是乎我们自己实现一个EntityManager 提交的方法。
EntityManager批量提交
我们改造一下EntityManager的批量提交的方法,不用isNew来进行提交:
Optional<SysUser> optional = iSysUserRepository.findById("2c987c3167a23e990167a240e0c80008"); SysUser user = optional.get(); List<SysUser> sysUsers = new ArrayList<>(); Long startTime = System.currentTimeMillis(); if (optional.isPresent()) { // 提交1W個 for (int i = 0; i < 10000; i++) { SysUser sysUser = new SysUser(); sysUser.setEmail(user.getEmail()); sysUser.setLoginName(user.getLoginName()); sysUser.setPassword(user.getPassword()); sysUser.setPhone(user.getPhone()); sysUser.setStatus(user.getStatus()); sysUser.setUserName(user.getUserName()); sysUser.setModitime(new Date()); sysUser.setSysOrganization(user.getSysOrganization()); sysUser.setSysRoles(sysUser.getSysRoles()); sysUser.setSysStation(sysUser.getSysStation()); sysUsers.add(sysUser); } for (int i = 0; i < sysUsers.size(); i++) { entityManager.persist(sysUsers.get(i)); if (i % 50 == 0) { entityManager.flush(); entityManager.clear(); } } } Long endTime = System.currentTimeMillis(); System.out.println("耗时:" + (endTime - startTime) + "ms");
效率略有提升。再测一下。
提交了10W数据,20秒。
NamedParameterJdbcTemplate批量提交
使用NamedParameterJdbcTemplate进行批量提交
@Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; //...... Optional<SysUser> optional = iSysUserRepository.findById("2c987c3167a23e990167a240e0c80008"); SysUser user = optional.get(); List<SysUser> sysUsers = new ArrayList<>(); Long startTime = System.currentTimeMillis(); if (optional.isPresent()) { // 提交1W個 for (int i = 0; i < 10000; i++) { SysUser sysUser = new SysUser(); sysUser.setId(String.valueOf(i)); sysUser.setEmail(user.getEmail()); sysUser.setLoginName(user.getLoginName()); sysUser.setPassword(user.getPassword()); sysUser.setPhone(user.getPhone()); sysUser.setStatus(user.getStatus()); sysUser.setUserName(user.getUserName()); sysUser.setModitime(new Date()); sysUser.setSysOrganization(user.getSysOrganization()); sysUser.setSysRoles(sysUser.getSysRoles()); sysUser.setSysStation(sysUser.getSysStation()); sysUsers.add(sysUser); } String sql = "insert into sys_user(id,email,login_name,moditime,password,phone,status,user_name) values (:id,:email,:loginName,:moditime,:password,:phone,:status,:userName)"; SqlParameterSource[] sqlParameterSource = SqlParameterSourceUtils.createBatch(sysUsers); namedParameterJdbcTemplate.batchUpdate(sql, sqlParameterSource); Long endTime = System.currentTimeMillis(); System.out.println("耗时:" + (endTime - startTime) + "ms"); }
再测一下
居然要50秒。
相关文章推荐
- Java后端爱上SpringBoot 第六节:SpringBoot定时任务及异步调用
- Java后端爱上SpringBoot 第七节:SpringBoot中缓存应用
- Java 批量生成二维码图片,并打包成可直接下载的zip包(spring boot)
- java鬼混笔记:springboot 9、springboot整合mybatis加上分页功能
- Intellij IDEA创建 java 后端 SpringBoot项目
- java springboot上传图片form表单提交上传
- java鬼混笔记:springboot 7、springboot整合mybatis后再加上druid数据库连接池
- c#通过post提交给java spring boot,utf-8 % & 乱码的问题。
- java鬼混笔记:springboot 2、springboot修改访问端口
- java鬼混笔记:springboot 5、springboot的Scheduled定时器:fixedDelay和fixedRate区别
- Spring Boot + Java爬虫 + 部署到Linux(六、后端Controller实现、下载文件以及登录验证拦截器)
- wex5与springboot前后端分离
- SpringBoot系列——Java配置(SpringMVC配置)
- 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?
- 详解Spring Boot 使用Java代码创建Bean并注册到Spring中
- SpringBoot中使用AMQ的两种方式二(Java配置、注解方式)
- springboot(十九):使用Spring Boot Actuator监控应用
- 39套Java架构师springboot,springcloud,dubbo,rocketmq,redis,tomcat大型分布式电商项目实战
- java 电子商务云平台b2b b2c o2o springmvc+mybatis+spring cloud+spring boot
- Springboot前后端交互