您是对的,默认情况下 Spring Data JPA 不会以有效的方式进行批量插入。当我们想将超过 25000 个对象批量写入一个表并且我们有 8 个这样的表要写入时,我们遇到了这个问题。这是我们如何做到的。
默认情况下,Spring Data JPA 会将对象获取到 EntityManager 的缓存中,然后比较并决定是调用持久化还是合并。我绕过了这个逻辑,因为我根据版本知道我是要坚持还是合并。诀窍是根据if (entity.getVersion() == 0) {
public List<T> update(Collection<T> entities) {
List<T> ret = new ArrayList<>();
EntityManager em = getEntityManager();
for (T entity : entities) {
if (entity.getVersion() == 0) {
em.persist(entity);
ret.add(entity);
} else {
ret.add(em.merge(entity));
}
}
return ret;
}
您将需要 EntityManager 的句柄,您可以通过创建自己的 JPA 存储库实现来获得它,只需扩展 SimpleJpaRepository 类。
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
public class MyJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
private EntityManager entityManager;
public MyJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
// Keep the EntityManager around to used from the newly introduced methods.
this.entityManager = entityManager;
}
public EntityManager getEntityManager() {
return entityManager;
}
}
并在应用程序的 SpringConfig 上添加以下注释来实例化您的 repo 实现,而不是使用默认的 SimpleJpaRepository@EnableJpaRepositories(basePackages = "..." , repositoryBaseClass = MyJpaRepositoryImpl.class)
@Configuration
@EnableJpaRepositories(basePackages = "au.com.xyz.infrastructure.repositories" , repositoryBaseClass = MyJpaRepositoryImpl.class)
@ComponentScan(basePackages = {"au.com.xyz.infrastructure.repositories.plugin", "au.com.xyz.infrastructure.repositories.external", ...})
public class InfrastructureSpringConfig {