首页 > 其他分享 >使用spring data jpa开启高性能批量insert/update

使用spring data jpa开启高性能批量insert/update

时间:2024-03-21 16:13:12浏览次数:25  
标签:insert hibernate jpa spring batchSize entities properties

1、jdbc url加上参数

&rewriteBatchedStatements=true

2、yaml/properties加上配置

spring.jpa.properties.hibernate.jdbc.batch_size: 2000
spring.jpa.properties.hibernate.jdbc.batch_versioned_data: true
spring.jpa.properties.hibernate.order_inserts: true
spring.jpa.properties.hibernate.order_updates: true
spring.jpa.properties.hibernate.generate_statistics: false

3、BatchRepository

@Slf4j
@Repository
public class BatchRepository {

    @PersistenceContext
    protected EntityManager entityManager;

    /**
     * Spring Data JPA调用的是Hibernate底层的实现。每次批量保存时,攒够 batchSize 条记录再集中em.flush(),
     *
     * @see org.hibernate.cfg.BatchSettings#STATEMENT_BATCH_SIZE
     */
    @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
    private Integer batchSize;

    /**
     * @see org.hibernate.cfg.BatchSettings#BATCH_VERSIONED_DATA
     */
    @Value("${spring.jpa.properties.hibernate.jdbc.batch_versioned_data}")
    private String batchVersionedData;

    /**
     * @see org.hibernate.cfg.BatchSettings#ORDER_INSERTS
     */
    @Value("${spring.jpa.properties.hibernate.order_inserts}")
    private String orderInserts;

    /**
     * @see org.hibernate.cfg.BatchSettings#ORDER_UPDATES
     */
    @Value("${spring.jpa.properties.hibernate.order_updates}")
    private String orderUpdates;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    @PostConstruct
    public void init() {
        log.info("BaseDao初始化加载。batchSize:{},batchVersionedData:{},orderInserts:{},orderUpdates:{}",
                batchSize, batchVersionedData, orderInserts, orderUpdates);
    }

    /**
     * 批量 insert,实现了性能呈倍提升。注意: <br>
     * 1. 需要配置 {@link #batchSize},且jdbc.url开启rewriteBatchedStatements为true <br>
     * 2. 关于rewriteBatchedStatements,可参考MySQL官网解释:{@linkplain 'https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-performance-extensions.html#cj-conn-prop_rewriteBatchedStatements'}
     * 3. 主键不能用生成策略,否则会报:{@link org.springframework.dao.InvalidDataAccessApiUsageException}: detached entity passed to persist
     *
     * @param entities 实体对象列表
     * @param <T>      实体类型(必须有@Entity注解)
     * @see #batchSize
     */
    @Transactional(rollbackFor = Exception.class)
    public <T> void batchInsert(List<T> entities) {
        if (entities == null || entities.isEmpty()) {
            return;
        }
        for (T entity : entities) {
            entityManager.persist(entity);
        }
    }

    /**
     * 批量update ( 通过Hibernate进行实现 )
     *
     * @param entities 实体对象列表
     * @param <T>      实体类型(必须有@Entity注解)
     * @see #batchSize
     */
    @Transactional(rollbackFor = Exception.class)
    public <T> void batchUpdate(List<T> entities) {
        if (entities == null || entities.isEmpty()) {
            return;
        }
        Session session = this.entityManager.unwrap(Session.class);
        session.setJdbcBatchSize(batchSize);
        for (T t : entities) {
            session.update(t);
        }
    }
}

4、性能验证
写入1000条
1000条逐条save耗时:55秒
saveAll:22秒
batchInsert(rewriteBatchedStatements=false): 10秒
batchInsert(rewriteBatchedStatements=true且开启第2步里的配置): 0.39秒

可见开启与不开启的性能差距达几十倍以上。

标签:insert,hibernate,jpa,spring,batchSize,entities,properties
From: https://www.cnblogs.com/jiayuan2006/p/18087603

相关文章

  • Spring bean的生命周期
    BeanDefinition的产生:SpringBoot在启动过程中,主要是刷新上下文的时候会将绝大部分的需要的bean生成BeanDefinition加入到容器(DefaultListableBeanFactory的beanDefinitionMap)  Bean的生命周期:会在SpringBoot启动过程中的刷新上下文的finishBeanFactoryInitialization方法......
  • Springboot实现qq邮件的发送
    一、打开必要的邮件设置首先登录qq邮箱官网登录之后,在设置中将传输协议给打开,我们需要用这个秘钥作为发件人的邮箱授权。这里开启之后,记住这个秘钥。二、代码编写首先我们将作为发送邮件的账户信息写入配置文件。spring:mail:host:smtp.qq.comusername......
  • SpringCloud 使用feign进行文件MultipartFile传输
    SpringCloud组件fiegn默认是不支持传递文件的。但是提供了feign-form扩展工具解决方法:步骤一:在消费者服务中加入相关pom依赖。<!--解决SpringCloud组件feign默认是不支持传递文件的--><dependency><groupId>io.github.openfeign.form</groupId>......
  • 从零开始学Spring Boot系列-集成Kafka
    Kafka简介ApacheKafka是一个开源的分布式流处理平台,由LinkedIn公司开发和维护,后来捐赠给了Apache软件基金会。Kafka主要用于构建实时数据管道和流应用。它类似于一个分布式、高吞吐量的发布-订阅消息系统,可以处理消费者网站的所有动作流数据。这种动作流数据包括页面浏览、搜索......
  • Spring基础
    IOC控制反转如A类中依赖了B类,传统生成实例的过程是需要先实例化B,在实例化A时传入B;控制反转实现了先实例化A,扫描到需要使用B时再实例化B实现了实例化过程的解耦,A、B可以单独实例化,再实现依赖关系Spring容器管理时的循环依赖问题三级缓存解决循环依赖三级缓存实际对应的是三次......
  • Spring MVC初体验
    使用maven框架构建SpringMVC项目,工具idea2023.2,jdk17,tomcat10。(之前使用tomcat9,与jdk17不兼容导致项目失败。在这个过程中失败很多次,有各种各样的原因,分别找到原因解决。)参考之前一篇文章SpringBootWeb项目整合jsp页面访问(非web项目改为web项目适用)。项目结构:......
  • springboot下postgresql指定schema问题
    首先明确用的postgresql版本是PostgreSQL9.5.25,compiledbyVisualC++build1800,64-bitspringboot是2.3.5.RELEASE。现有的文档提供的连接数据库配置方式是url:jdbc:postgresql://IP:端口/数据库名?currentSchema=模式名&stringtype=unspecified通常postgresq......
  • Vue.js+SpringBoot开发服装店库存管理系统
    目录一、摘要1.1项目介绍1.2项目录屏二、功能模块2.1数据中心模块2.2角色管理模块2.3服装档案模块2.4服装入库模块2.5服装出库模块三、系统设计3.1用例设计3.2数据库设计3.2.1角色表3.2.2服装档案表3.2.3服装入库表3.2.4服装出库表四、系统展示五、核......
  • Vue.js+SpringBoot开发高校宿舍调配管理系统
    目录一、摘要1.1项目介绍1.2项目录屏二、功能需求2.1学生端2.2宿管2.3老师端三、系统展示四、核心代码4.1查询单条个人习惯4.2查询我的室友4.3查询宿舍4.4查询指定性别全部宿舍4.5初次分配宿舍五、免责说明一、摘要1.1项目介绍基于JAVA+Vue+Spring......
  • 基于java+springboot+vue实现的电影院选票系统(文末源码+Lw+ppt)23-467
    摘要时代在飞速进步,每个行业都在努力发展现在先进技术,通过这些先进的技术来提高自己的水平和优势,电影院选票系统当然不能排除在外。电影院选票系统是在实际应用和软件工程的开发原理之上,运用java语言,前台Vue框架以及后台SpringBoot框架进行开发。首先要进行需求分析,分析出电......