如何在Hibernate中执行批量插入更新?
在这篇文章中,我们将了解如何在Hibernate中执行批量插入/更新。
每当我们执行SQL语句时,我们都是通过向数据库发出网络请求来完成的。现在,如果我们要向数据库表中插入10个条目,则需要发出10次网络请求。相反,我们可以通过使用批处理来优化我们的网络请求。批处理允许我们通过单个网络请求执行一组SQL语句。
为了理解和实现这一点,让我们定义我们的实体 -
@Entity public class Parent { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; // Getters //Setters }
要在Hibernate中启用批处理,我们需要在应用程序属性文件中添加一个属性
spring.jpa.properties.hibernate.jdbc.batch_size=3
现在,我们需要执行EntityManager的persist函数以将数据插入数据库
示例
@Autowired private EntityManager entityManager; @Test Public 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=true spring.jpa.properties.hibernate.batch_versioned_data=true
示例
更新数据的代码 -
@Autowired private EntityManager entityManager; @Test public 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。
广告