Skip to main content
 首页 » 编程设计

Spring Data JPA 实现批量插入

2022年07月19日162bonelee

Spring Data JPA 实现批量插入

数据库操作是非常昂贵的,我们可以通过采用批量操作提升性能并维护一致性。本文通过示例说明Spring Data JPA的批量操作。

1. 环境准备

1.1. 依赖

<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-data-jpa</artifactId> 
   <version>2.1.3.RELEASE</version> 
</dependency> 
<dependency> 
    <groupId>com.h2database</groupId> 
    <artifactId>h2</artifactId> 
    <version>1.4.197</version> 
</dependency> 

你可以选择最新版本,这里为了方便采用h2数据库。

1.2. 实体类

这里简单定义实体类Customer:

Entity 
public class Customer { 
  
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String firstName; 
    private String lastName; 
  
    // constructor, getters, setters  
} 

1.2. 定义Repository

接着定义Repository:

public interface CustomerRepository extends CrudRepository<Customer, Long> { 
} 

下面利用saveAll方式实现批量插入。

1.3. 定义Controller

在Controller中注入customerRepository,调用saveAll方法实现批量插入:

@RestController 
public class CustomerController {    
    @Autowired 
    CustomerRepository customerRepository;    
  
    @PostMapping("/customers") 
    public ResponseEntity<String> insertCustomers() {         
        Customer c1 = new Customer("James", "Gosling"); 
        Customer c2 = new Customer("Doug", "Lea"); 
        Customer c3 = new Customer("Martin", "Fowler"); 
        Customer c4 = new Customer("Brian", "Goetz"); 
        List<Customer> customers = Arrays.asList(c1, c2, c3, c4); 
        customerRepository.saveAll(customers); 
        return ResponseEntity.created("/customers"); 
    } 
  
    // ... @GetMapping to read customers 
} 

1.4. 测试验证

@Autowired 
private MockMvc mockMvc; 
  
@Test 
public void whenInsertingCustomers_thenCustomersAreCreated() throws Exception { 
    this.mockMvc.perform(post("/customers")) 
      .andExpect(status().isCreated())); 
} 

这样就完成了批量插入操作,真的能起作用吗?下面我们配置日志进行验证。

2. 验证批量操作

为了验证,我们在application.properties文件中增加下面属性看一些统计信息:

spring.jpa.properties.hibernate.generate_statistics=true 

这是运行测试程序,看下面统计数据:

11232586 nanoseconds spent preparing 4 JDBC statements; 
4076610 nanoseconds spent executing 4 JDBC statements; 
0 nanoseconds spent executing 0 JDBC batches; 

从上面信息可以看到,确实创建了4个customer,但在批操作中没有它们。原因是在有些情况下批量操作默认没有启用,我们示例中id是自动生成的,这时saveAll缺省不采用批量操作。现在我们启用批量操作相关配置:

spring.jpa.properties.hibernate.jdbc.batch_size=4 
spring.jpa.properties.hibernate.order_inserts=true 

第一个属性告诉Hibernate收集插入批为4。 order_insert属性告诉Hibernate花时间按实体对插入进行分组,从而创建更大的批。

接着第二次运行测试,输出日志为:

16577314 nanoseconds spent preparing 4 JDBC statements; 
2207548 nanoseconds spent executing 4 JDBC statements; 
2003005 nanoseconds spent executing 1 JDBC batches; 

对于更新和删除也可以使用相同的方法,Hibernate也提供了order_updates属性。

3. 总结

使用批量插入可以提升性能。Spring Data Jpa 在一些情况下自动禁用批量功能,需要手动启用。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/103783191