[英]How to persist a lot of entities (JPA)
我需要處理一個CSV文件,並且每個記錄(行)都會保留一個實體。 現在,我這樣做:
while ((line = reader.readNext()) != null) {
Entity entity = createEntityObject(line);
entityManager.save(entity);
i++;
}
其中save(Entity)
方法基本上只是一個EntityManager.merge()
調用。 CSV文件中大約有20,000個實體(行)。 這是一種有效的方法嗎? 這似乎很慢。 使用EntityManager.persist()
會更好嗎? 這種解決方案是否有任何缺陷?
編輯
這是一個漫長的過程(超過400s),我嘗試了兩種解決方案, persist
和merge
。 兩者的完成時間大致相同(459s vs 443s)。 問題是如果逐個保存實體是最佳的。 據我所知,Hibernate(我的JPA提供程序)確實實現了一些緩存/刷新功能,所以我不必擔心這一點。
JPA API沒有為您提供最佳選擇。 根據您想要的速度,您將不得不尋找特定於ORM的選項 - 在您的情況下使用Hibernate。
要檢查的事項:
所以在Ebean ORM中這將是:
EbeanServer server = Ebean.getServer(null);
Transaction transaction = server.beginTransaction();
try {
// Use JDBC batch API with a batch size of 100
transaction.setBatchSize(100);
// Don't bother getting generated keys
transaction.setBatchGetGeneratedKeys(false);
// Skip cascading persist
transaction.setPersistCascade(false);
// persist your beans ...
Iterator<YourEntity> it = null; // obviously should not be null
while (it.hasNext()) {
YourEntity yourEntity = it.next();
server.save(yourEntity);
}
transaction.commit();
} finally {
transaction.end();
}
哦,如果你通過原始JDBC執行此操作,則跳過ORM開銷(減少對象創建/垃圾收集等) - 所以我不會忽略該選項。
所以,是的,這不能回答您的問題,但可能有助於您搜索更多ORM特定的批量插入調整。
我認為這樣做的一種常見方式是交易。 如果您開始新事務然后持久存儲大量對象,則在提交事務之前,它們實際上不會插入到數據庫中。 如果您要提交大量項目,這可以提高效率。
您可以使用經典的SQL Insert語句將它們直接寫入數據庫。
為了使它更快,至少在Hibernate中,你會在一定數量的插入后執行flush()和clear()。 我已經為數百萬條記錄做了這種方法並且它有效。 它仍然很慢,但它比不這樣做要快得多。 基本結構是這樣的:
int i = 0;
for(MyThingy thingy : lotsOfThingies) {
dao.save(thingy.toModel())
if(++i % 20 == 0) {
dao.flushAndClear();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.