Spring Data JPAバッチ挿入

1. 概要

データベースに出かけるのは高価です。 複数の挿入を1つにバッチ処理することで、パフォーマンスと一貫性を改善できる場合があります。
このチュートリアルでは、https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa [Spring Data JPA]を使用してこれを行う方法を見ていきます。

2. Spring JPAリポジトリ

まず、単純なエンティティが必要です。 _Customer_と呼びましょう:
@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String firstName;
    private String lastName;

    // constructor, getters, setters
}
次に、リポジトリが必要です。
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
*これにより、_saveAll_メソッドが公開され、複数の挿入が1つにまとめられます。*
それで、コントローラでそれを活用しましょう:
@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
}

3. エンドポイントのテスト

MockMvcを使用すると、コードを簡単にテストできます。
@Autowired
private MockMvc mockMvc;

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

4. バッチ処理を行っていますか?

*したがって、実際にはもう少し設定があります*-違いを示すために簡単なデモを行いましょう。
まず、次のプロパティを__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人の顧客を作成しました。これは素晴らしいことですが、*バッチ内には誰もいません*。
*理由は、バッチ処理がデフォルトでオンになっていない場合があるためです。*
私たちの場合、それはid自動生成を使用しているためです。 したがって、*デフォルトでは、_saveAll_は各挿入を個別に行います。*
それで、スイッチを入れましょう:
spring.jpa.properties.hibernate.jdbc.batch_size=4
spring.jpa.properties.hibernate.order_inserts=true
最初のプロパティは、Hibernateに4つのバッチで挿入を収集するように指示します。 _order_inserts_プロパティは、Hibernateがエンティティごとに挿入をグループ化する時間を取り、より大きなバッチを作成するように指示します。
*したがって、テストを2回実行すると、挿入がバッチ処理されたことがわかります。*
16577314 nanoseconds spent preparing 4 JDBC statements;
2207548 nanoseconds spent executing 4 JDBC statements;
2003005 nanoseconds spent executing 1 JDBC batches;
削除と更新にも同じアプローチを適用できます(* Hibernateには__order_updates __property *もあります)。

5. 結論

バッチ挿入機能により、パフォーマンスの向上が見られます。
もちろん、場合によってはバッチ処理が自動的に無効になることを認識しておく必要があり、出荷前にこれを確認して計画する必要があります。
これらのすべてのコードスニペットhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-jpa[GitHub上]を必ず確認してください。