如何在单个语句中插入所有行。这是我的代码,但插入行需要很长时间。
for(Myobject object : objectList)
getCurrentSession().save(object);
它为每条记录创建一个语句;
insert into myobject (id, type) values (?, ?)
insert into myobject (id, type) values (?, ?)
....
我想做的是;
insert into myobject (id, type) values (?, ?), (?, ?), (?, ?) ......(?, ?);
有没有办法创建这个声明?
答案 0 :(得分:3)
您可能对batch inserts on Hibernate tutorial感兴趣。
问题不在于save()
操作,因为所有正在执行此操作的是将对象保存在第一级缓存中(在会话中,使其持久化),但是flush()
触发插入的操作。他们建议采用以下方法,以实现良好的性能。
在教程中也有人说 - 我还没有尝试过 - 你可以获得OutOfMemoryException
非常多的持久性行,他们似乎建议20
作为批量大小。< / p>
在使新对象持久化flush()然后清除()会话时,为了控制第一级缓存的大小。
for ( int i=0; i<objectList.size(); i++ ) {
getCurrentSession().save(objectList.get(i));
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
编辑如果需要,还可以将配置文件中的hibernate.jdbc.batch_size
设置为20.或50。 Hibernate必须对它们进行分组,而不是20个插入,你应该只有一个按20分组:
into myobject (id, type) values (id1, val1), (id2, val2), ......(id20, val20)
答案 1 :(得分:1)
我想添加一种设法使用"status": "ACTIVE",
accountProfileId: "Premium",
"accountNumber": "123",
"billingAddress": [
{
"key": "Children",
"value": "y"
}
解决此问题的方法。我从@Bohemian答案中获得了一些启发。首先,在 Service 层上,将对象列表分成多个块,然后在 DAO 层上,插入每个块。
服务
Native Queries
DAO
@Override
public void massInsert(List<Object> objects) throws Exception {
// First, let's split the list in chunks.
final int chunkSize = 50;
final AtomicInteger counter = new AtomicInteger();
final Collection<List<Object>> result =
objects.stream().collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize)).values();
// Now, for each iteration, we will insert the corresponding details.
for (List<Objects> oList : result) {
this.dao.massInsert(oList);
}
}
它的工作比逐行插入每一行要快得多。希望对您有所帮助。
答案 2 :(得分:0)
使用本机查询(原始SQL):
entityManager
.createNativeQuery("insert into myobject (id, type) values (?, ?), (?, ?), (?, ?) ......(?, ?)")
.setParameter(1, foo)
// etc
.execute();
答案 3 :(得分:0)
只需为hibernate启用&#34; DEBUG&#34;级别日志记录,并查看批量插入是否正在发生。
log4j.rootLogger=TRACE, file, stdout
log4j.logger.org.hibernate=TRACE
log4j.logger.org.hibernate.type=ALL
你应该看到如下的日志。
DEBUG AbstractBatcher:66 - Executing batch size: 20
在调用ps.executeBatch()之前,很快就会生成插入语句。 org.hibernate.jdbc.BatchingBatcher的第70行。