如何在 JPA 和自定义 UUID 标识符中实现批量插入
Posted
技术标签:
【中文标题】如何在 JPA 和自定义 UUID 标识符中实现批量插入【英文标题】:How to implement Batch insert in JPA and a Custom UUID Identifier 【发布时间】:2021-08-02 17:04:13 【问题描述】:所以,我使用 Springboot 和 Data-JPA 和 POSTGRESQL 将数据插入表中:
@Entity
@Builder
@Data
class Person
@Id
UUID id;
String name;
以及它的存储库
@Repository
interface PersonRepository extends JPARepository<Person, UUID>
假设我们创建了一个人员列表。
List<Person> persons = List.of(....)
Lets assume we have 10 persons in the list..
现在,当我执行 personRepository.saveAll(persons);
所以我遇到了这些问题:
-
insert 之前有 10 个 insert 语句和 select select 语句。
我想要大小为 5 的批量插入,因此我想要在此处触发 2 个多值插入语句,但正在触发 10 个插入。
现在,我在自定义存储库的帮助下解决了第 1 点
public interface CustomBaseRepository<T, ID extends Serializable>
<S extends T> S customInsert(S entity);
<S extends T> Collection<S> customInsertAll(Collection<S> entities);
<S extends T> Collection<S> customSaveAllInBatch(Collection<S> entities);
@Transactional
public class CustomBaseRepositoryImpl<T, ID extends Serializable> implements CustomBaseRepository<T, ID>
@Autowired
private final EntityManager entityManager;
public CustomBaseRepositoryImpl(EntityManager entityManager)
this.entityManager = entityManager;
@Override
public <S extends T> S customInsert(S entity)
entityManager.persist(entity);
return entity;
@Override
public <S extends T> Collection<S> customInsertAll(Collection<S> entities)
entities.forEach(entityManager::persist);
return entities;
@Override
<S extends T> Collection<S> customSaveAllInBatch(Collection<S> entities)
**//TODO(...): HOW TO DO THIS?**
所以我创建了我的自定义存储库并公开了 EntityManager 并进行了持久化,因为我知道当我保存“人员”列表时,它都是新记录。
现在,SELECT before INSERT 问题已修复,但批量插入问题仍然存在..
我也尝试使用 personRepository.saveAll(persons),但没有用,我在应用程序属性中使用这些命令也启用了批处理,但无法使其工作。
请帮助我实现批量插入,即在单个插入语句中插入多条记录..
我尝试使用这些属性但没有用:
spring.jpa.properties.hibernate.jdbc.batch_size
spring.jpa.properties.hibernate.jdbc.order_inserts
Also for URL:
reWriteBatchedInserts was enabled.
请帮帮我..
【问题讨论】:
【参考方案1】:-
只需修改您的实体以在插入之前自动生成实体 ID。并且选择会消失。无需为此创建自定义存储库
@Entity
@Builder
@Data
class Person
@Id
@GeneratedValue(generator = "uuid") // new line !!!
@GenericGenerator(name = "uuid", strategy = "uuid2") //new line !!
UUID id;
String name;
-
至于批量插入,在您使用我之前的建议并使用 vanilla Spring Data 存储库后,您可能想试试这个
spring.jpa.properties.hibernate.jdbc.batch_size=10
spring.jpa.properties.hibernate.order_inserts=true
【讨论】:
1.但是,由于我需要 Java 层中预先存在的人员 ID 进行其他计算,所以我继续采用这种方法,是否有任何其他优化方法来处理您在 Java 层上生成 ID 并仅实现的情况插入没有选择? 2. 我尝试使用第二部分 w.r.t 到 1 中提到的步骤,我仍然得到多个插入。 嗯。让我想想。另外,您确定将人员保存到数据库后不能进行其他计算吗? 嗯,是的,我需要在持久化之前预先计算 ID。 请告诉我,你怎么知道批次实际上并没有发生? 我启用了休眠日志,所以我给出了 2 的批量大小,并且节省了 10 人,所以最终应该触发 5. 查询,对吗?但我看到了 10 个插页。我希望我做对了以上是关于如何在 JPA 和自定义 UUID 标识符中实现批量插入的主要内容,如果未能解决你的问题,请参考以下文章