在 spring 数据 jpa 中为不同的存储库定义不同的批量大小

Define different batch sizes in spring data jpa for different repositories

我在同一个 Spring 引导项目中有 2 个不同的存储库。

我想为 2 个不同的存储库定义不同的批次大小。但是,我找不到 Spring Data Jpa 配置的任何解决方案。

存储库如下:

@Repository
public interface ItemRepository extends JpaRepository<Item, String> {
   Page<Item> findItemByCreationDateBefore(Timestamp creationDate, Pageable pageable);
}


@Repository
public interface CarRepository extends JpaRepository<Car, String> {
   @Query("SELECT c FROM Car c WHERE c.journeyCode = :journeyCode " +
          "AND c.currentLocationId = :currentLocationId")
   Page<Delivery> findCars(Long journeyCode, Long currentLocationId, Pageable pageable);
}

batch size配置如下

    jpg:
      spring:
        properties:
          hibernate:
            jdbc:
              batch_size: 4
            order_inserts: true
            order_updates: true

是否可以这样配置批量大小?如果可能的话,我该如何实现?

理论上您可以尝试通过以下方式实现 BatchBuilder 接口:

import java.util.Map;

import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.batch.internal.BatchBuilderMXBean;
import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.Manageable;


public class MyBatchBuilder implements BatchBuilder, Configurable, Manageable, BatchBuilderMXBean
{
   private int jdbcBatchSize;
   
   public MyBatchBuilder()
   {
   }
   
   public MyBatchBuilder(int jdbcBatchSize) {
      this.jdbcBatchSize = jdbcBatchSize;
   }

   @Override
   public void configure(Map configurationValues) {
      jdbcBatchSize = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, jdbcBatchSize );
   }

   @Override
   public int getJdbcBatchSize() {
      return jdbcBatchSize;
   }

   @Override
   public void setJdbcBatchSize(int jdbcBatchSize) {
      this.jdbcBatchSize = jdbcBatchSize;
   }
   
   @Override
   public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator)
   {
      final Integer sessionJdbcBatchSize = jdbcCoordinator.getJdbcSessionOwner()
            .getJdbcBatchSize();
      final int jdbcBatchSizeToUse = sessionJdbcBatchSize == null ?
            this.jdbcBatchSize :
            sessionJdbcBatchSize;

      // getEntityName() + "#DELETE"
      // getEntityName() + "#UPDATE"
      BasicBatchKey insertCarBatchKey = new BasicBatchKey("com.your.entities.Car#INSERT", null);
      final int jdbcBatchSizeForCar = 20;
      if (insertCarBatchKey.equals(key))
      {
         return new BatchingBatch( key, jdbcCoordinator, jdbcBatchSizeForCar );
      }

      return new BatchingBatch( key, jdbcCoordinator, jdbcBatchSizeToUse );
   }
}

然后将以下属性添加到您的 spring 应用程序配置中:

spring.jpa.properties.hibernate.jdbc.batch.builder=com.your.app.MyBatchBuilder
spring.jpa.properties.hibernate.jdbc.batch_size=4

但是正如 hibernate documentation 中所述,从 Hibernate 的默认实现切换几乎不是一个好主意。所以,也许在评论中建议的方式会更符合您的需求。

P.S。也正如休眠文档中所述:

Since version 5.2, Hibernate allows overriding the global JDBC batch size given by the hibernate.jdbc.batch_size configuration property on a per Session basis.

entityManager
    .unwrap( Session.class )
    .setJdbcBatchSize( 10 );