每当我们执行一条sql语句时,我们都是通过对数据库进行网络调用来完成的。现在,如果我们必须向数据库表中插入 10 个条目,那么我们必须进行 10 次网络调用。相反,我们可以通过使用批处理来优化网络调用。批处理允许我们在单个网络调用中执行一组 sql 语句。
为了理解和实施这一点,让我们定义我们的实体−
@entitypublic class parent { @id @generatedvalue(strategy = generationtype.auto) private long id; private string name; // getters //setters}
为了在hibernate中启用批处理,我们需要向我们的应用程序添加一个属性
properties文件:
spring.jpa.properties.hibernate.jdbc.batch_size=3
现在,我们需要执行entitymanager的persist函数将数据插入数据库
示例@autowiredprivate entitymanager entitymanager;@testpublic void insertinbatch(){ for (int i = 0; i < 6; i++) { parent parent = parent[i]; entitymanager.persist(parent); }}
输出batch:true, querysize:1, batchsize:3, query:[insert into parent (name, id) values (?, ?)], params:[[p1,1],[p2,2],[p3,3]]batch:true, querysize:1, batchsize:3, query:[insert into parent (name, id) values (?, ?)], params:[[p4,4],[p5,5],[p6,6]]
从控制台我们可以看到,插入父表的操作是在批量大小为3的情况下进行的。
在持久化实体时,可能会发生outofmemoryexception,因为hibernate将实体存储在持久化上下文中。因此,出于优化目的,我们可以在每批之后使用实体管理器的flush()和clear()。
批量更新意味着在一次网络调用中更新大量数据。
对于批量更新,流程是相同的。我们需要在应用程序属性文件中添加以下两个语句,然后执行更新过程。
spring.jpa.properties.hibernate.order_updates=truespring.jpa.properties.hibernate.batch_versioned_data=true
示例更新数据的代码−
@autowiredprivate entitymanager entitymanager;@testpublic void updateinbatch() { typedquery<parent> query = entitymanager.createquery(select p from parent p, parent.class); list<parent> parents = query.getresultlist(); int i=1; for (parent parent : parents) { string s=parent+integer.tostring(i); i++; parent.setname(s); }}
hibernate 现在会将这些语句绑定在一个批处理中并执行它们。
输出batch:true, querysize:1, batchsize:3, query:[update parent set name=? where id=?], params:[[parent1,1],[ parent2,2],[ parent3,3]]batch:true, querysize:1, batchsize:3, query:[update parent set name=? where id=?], params:[[parent4,4],[parent5,5],[parent6,6]]
从控制台可以看到,父表中的数据更新是在批量大小为3的情况下进行的。
以上就是如何在hibernate中执行批量插入更新操作?的详细内容。
