在正式地介绍hibernate批量操作之前,先给大家普及一个hibernate重要的成员,即hibernate一级缓存,这个一级缓存不像二级缓存那样可插拔似的,是无条件使用的,这个缓存最大的一个作用就是在一个事务中,如果进行了n次对象保存的操作,都会缓存到hibernate的一级缓存区中,直至刷新缓存或提交事务,否则这些对象会一直存在于缓存中,好了,看下面这个例子:

EntityManager entityManager = null;
EntityTransaction txn = null;
try {
entityManager = entityManagerFactory().createEntityManager();

txn = entityManager.getTransaction();
txn.begin();

for ( int i = 0; i < 100000
; i++ ) {
Person Person = new Person( String.format( "Person %d", i ) );
entityManager.persist( Person );
}
txn.commit();
} catch (RuntimeException e) {
if ( txn != null && txn.isActive()) txn.rollback();
throw e;
} finally {
if (entityManager != null) {
entityManager.close();
}
}

上述操作例子会导致如下几个问题:

1、由于hibernate的一级session缓存会缓存所有新插入的用户实例,所以等到整个事务结束,持久化容器需要同时管理100000个对象,此时虚拟机分配的最大缓存相当小,那么这个操作例子将会引发OutOfMemoryException,而失败,虽然Java8允许分配更大的内存给缓存用;

2、长时间的事务运行会耗损连接池的性能,以至于其它的事务可能会得不到执行;

针对上述问题,我们可以周期性地调用Session的成员方法flush()和clear()方法,来灵活的控制一级缓存的大小,比如每当缓存25个对象调用一次,在提交刷新缓存对象记录的同时,清空缓存,看下面这个例子:

EntityManager entityManager = null;
EntityTransaction txn = null;
try {
entityManager = entityManagerFactory().createEntityManager();
txn = entityManager.getTransaction();
txn.begin();
int batchSize = 25;
for ( int i = 0; i < entityCount; ++i ) {
Person Person = new Person( String.format( "Person %d", i ) );
entityManager.persist( Person );
if ( i % batchSize == 0 ) {
//flush a batch of inserts and release memory
entityManager.flush();
entityManager.clear();
}
}
txn.commit();
} catch (RuntimeException e) {
if ( txn != null && txn.isActive())

txn.rollback();
throw e;
} finally {
if (entityManager != null) {
entityManager.close();
}
}

上述方法是很常见的一个解决一级缓存过大的方法,下面在让我们换个思路使用Hibernate的StatelessSession类来解决这个问题: StatelessSession是一个由Hibernate提供的,面向命令的API,使用它可以以游离对象的方式读取或存入数据,需要注意的是它不提供一级缓存,不与任意二级缓存或查询缓存交互,不提供自动的脏数据检查等,但是需要注意的是在某些情况或事务下,这个无状态的Session要比有状态的Session要快很多,其余限制请查阅相关文档,在此不多做叙述,看例子:

StatelessSession statelessSession = null;
Transaction txn = null;
ScrollableResults scrollableResults = null;
try {
SessionFactory sessionFactory = entityManagerFactory().unwrap( SessionFactory.class );
statelessSession = sessionFactory.openStatelessSession();

txn = statelessSession.getTransaction();
txn.begin();

scrollableResults = statelessSession.createQuery( "select p from Person p" )
.scroll(ScrollMode.FORWARD_ONLY);

while ( scrollableResults.next() ) {
Person Person = (Person) scrollableResults.get( 0 );
// 对Person对象的操作

XXX
statelessSession.update( Person );
}

txn.commit();
} catch (RuntimeException e) {
if ( txn != null && txn.getStatus() == TransactionStatus.ACTIVE)

txn.rollback();
throw e;
} finally {
if (scrollableResults != null) {
scrollableResults.close();
}
if (statelessSession != null) {
statelessSession.close();
}
}

上述例子,正式利用的StatelessSession的特性,提出了一种新的解决缓存过大的思路,查询返回的客户实例会立即变为游离状态,他们不会与任何持久化容器关联,StatelessSession接口里面定义的insert、update、delete操作都是直接作用于数据库行,它们所出发的SQL操作会被立即执行,这一点与Session有着本质区别;

好了,先到这里吧!

在本文中,你将了解什么是批处理,为什么要使用它,以及如何在JPA和 Hibernate 中正确使用它。 在编写企业应用程序时,通常将工作分配在服务于典型OLTP(在线事务处理)传输的前端系统,和一个或多个批处理用于... 默认情况下,100个插入将导致100个SQLINSERT语句,这很糟糕,因为它导致100次数据库往返。批处理机制能够使用分组的机制INSERTs,UPDATEs,并DELETEs,作为一个结果,它显著减少数据库往返次数。实现 批量 插入的一种方法是使用SimpleJpaRepository#saveAll(Iterableentities)方法。在这里,我们用MySQL做到这一点。关键点:在app... <br />在 Hibernate 应用中如何处理 批量 更新和 批量 删除?<br />选自<<精通 Hibernate :Java对象持久化技术详解>> 作者:孙卫琴 来源:www.javathinker.org<br />如果转载,请标明出处,谢谢<br />9.4 批量 处理数据<br /> <br />通常,在一个Session对象的缓存中只存放数量有限的持久化对象,等到Session对象处理事务完毕,还要关闭Session对象,从而及时释放Session的缓存占用的内存。<br /> 批量 处理数据是指在一个事务中处 根据网络材料整理https://www.youtube.com/watch?v=EZwpOLCfuq4​www.youtube.com@column 是多余的字段默认就是被持久化的,不需要额外标记显式调用 save 是多余的无论调用了还是没调用 save,提交 session 的时候,dirty checking 发现的改动都会被 saveEntity别名给 Entity 重命名之后,hql 里也... 在 Hibernate 应用中, 批量 处理有两种方法,一种是通过 Hibernate 的缓存,另一种是绕过 Hibernate ,直接调用JDBC API来处理。 一: 批量 插入 (1)通过 Hibernate 的缓存进行 批量 插入 使用这种方法时,首先要在 Hibernate 的配置文件 hibernate .cfg.xml 中设置 批量 尺寸属性 hibernate .jdbc.batch_size ,且最好关闭Hibe... 可以在处理完成一个对象或小 批量 对象后,调用flush()方法强制同步缓存和数据库,然后调用clear()方法清空缓存。session.createQuery(hql).setParameter("name","财务部").executeUpdate();注意:该方式使用的连接依然是最初的连接对象,并且命令对象依然是根据连接创建的,注意这里是SQL语句,不是HQL语句。(1)使用HQL进行 批量 操作 数据库层面 executeUpdate()(2)使用JDBC API进行 批量 操作 数据库层面。 批量 处理数据:指的是在一个事务场景中需要处理大量数据。 Hibernate 进行 批量 处理数据的方式:1.使用HQL进行 批量 操作 :HQL是跨数据库的,面向对象,但具有局限性,只能用于单个持久化类,不支持连接,不能使用子查询2.使用JDBC API进行 批量 操作 操作 方式简单,可以在sql中使用不同数据库的特性3.使用Session进行 批量 操作 :把关系数据加载到内存中 操作 ,需要通...