【问题标题】:Insert multiple records with a single query using JPA methods使用 JPA 方法通过单个查询插入多条记录
【发布时间】:2019-09-18 08:30:58
【问题描述】:

我有一个 Spring Boot 应用程序,我想在其中使用单个 DB 查询插入多条记录:-

public void addEvents() {
        String sql = "INSERT INTO Data values(1,'Data 1'), (2,'Data 2'),(3,'Data 3')";
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        entityManager.createNativeQuery(sql).executeUpdate();
        entityManager.getTransaction().commit();
    }

实体类:-

@Entity
@Table
public class Data {
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;

    public Data(String name) {
        this.name = name;
    }

    public Data(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Data() {
    }
}

这里的数据是我要插入的实体。我需要在几秒钟内在我的数据库中插入超过 10000 行。因此,触发单独的 DB 调用成本太高。因此,我为此目的使用了一个查询。此查询是本机查询。谁能告诉我 JPA 是否提供了一个开箱即用的 API 来在单个 DB cl 中插入多个实体?

【问题讨论】:

  • 你可以在这里添加你的实体类吗?
  • @ShaunakPatel - 已添加,请立即查看
  • 我建议你应该有批处理作业来处理这种情况。在服务器不忙的时候(用户流量较少的时候)运行批处理作业插入这么多记录

标签: hibernate jpa spring-data-jpa spring-data


【解决方案1】:

您可以使用 spring-data 的 saveAll 方法进行批量插入。这是一个代码sn-p,

List<Data> dataList = <10000 records> //You need to prepare batch of 10000

dataRepository.saveAll(dataList) //Spring boot will handle batches automatically. 

application.properties中添加以下属性

spring.jpa.properties.hibernate.jdbc.batch_size=100

您可以使用spring.jpa.show-sql查看生成的查询

更新: 在您的 pom.xml 中添加以下依赖项,

 <dependency>
     <groupId>com.integralblue</groupId>
     <artifactId>log4jdbc-spring-boot-starter</artifactId>
            <version>1.0.2</version>
 </dependency>

如果批处理是否发生,上述依赖项将显示在日志中。

【讨论】:

  • 这里我可以看到有 1000 个 sql 查询被触发了。
  • 当我尝试插入 2 条数据记录时,会触发以下 4 个查询:- 休眠:从数据 data0_ 中选择 data0_.id 作为 id1_0_0_,将 data0_.name 作为 name2_0_0_ 其中 data0_.id=? Hibernate:为 hibernate_sequence 调用下一个值 Hibernate:从数据 data0_ 中选择 data0_.id 作为 id1_0_0_,data0_.name 作为 name2_0_0_ where data0_.id=? Hibernate: 调用 hibernate_sequence 的下一个值 Hibernate: 插入数据 (name, id) 值 (?, ?) Hibernate: 插入数据 (name, id) 值 (?, ?)
  • 您可以将您的代码添加到公共存储库中吗?我想看看。
  • 你可以在这里查看代码 -m github.com/PracticeOrganization09/Sample-Code
  • @Sunny,批处理已经在进行,但在日志中看不到。我已经更新了我的答案以显示批处理启用的行为。
猜你喜欢
  • 2013-11-06
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-19
相关资源
最近更新 更多