使用Hibernate将 100 000 条记录插入到数据库的一个很自然的做法可能是这样的
引用
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();
这段程序大概运行到 50 000 条记录左右会失败并抛出 内存溢出异常(OutOfMemoryException) 。 这是因为 Hibernate 把所有新插入的 客户(Customer)实例在 session级别的缓存区进行了缓存的缘故。
我们会在本章告诉你如何避免此类问题。首先,如果你要执行批量处理并且想要达到一个理想的性能, 那么使用JDBC的批量(batching)功能是至关重要。将JDBC的批量抓取数量(batch size)参数设置到一个合适值 (比如,10-50之间):
引用
hibernate.jdbc.batch_size 20
你也可能想在执行批量处理时关闭二级缓存:
引用
hibernate.cache.use_second_level_cache false
批量插入(Batch inserts)
如果要将很多对象持久化,你必须通过经常的调用 flush() 以及稍后调用 clear() 来控制第一级缓存的大小。
引用
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
//flush a batch of inserts and release memory:
//将本批插入的对象立即写入数据库并释放内存
session.flush();
session.clear();
}
}
tx.commit();
session.close();
批量更新(Batch updates)
此方法同样适用于检索和更新数据。此外,在进行会返回很多行数据的查询时, 你需要使用 scroll() 方法以便充分利用服务器端游标所带来的好处。
引用
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
if ( ++count % 20 == 0 ) {
//flush a batch of updates and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
大批量更新/删除(Bulk update/delete)
就像已经讨论的那样,自动和透明的 对象/关系 映射(object/relational mapping)关注于管理对象的状态。 这就意味着对象的状态存在于内存,因此直接更新或者删除 (使用 SQL 语句 UPDATE 和 DELETE) 数据库中的数据将不会影响内存中的对象状态和对象数据。 不过,Hibernate提供通过Hibernate查询语言(第 15 章 HQL: Hibernate查询语言)来执行大批 量SQL风格的(UPDATE)和(DELETE) 语句的方法。
UPDATE 和 DELETE语句的语法为: ( UPDATE | DELETE ) FROM? ClassName (WHERE WHERE_CONDITIONS)?。 有几点说明:
在FROM子句(from-clause)中,FROM关键字是可选的
在FROM子句(from-clause)中只能有一个类名,并且它不能有别名
不能在大批量HQL语句中使用连接(显式或者隐式的都不行)。不过在WHERE子句中可以使用子查询。
整个WHERE子句是可选的。
举个例子,使用Query.executeUpdate()方法执行一个HQL UPDATE语句:
引用
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer set name = :newName where name =
ldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法 (此方法是为 那些熟悉JDBC PreparedStatement.executeUpdate() 的人们而设定的)
引用
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer where name =
ldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
由Query.executeUpdate()方法返回的整型值表明了受此操作影响的记录数量。 注意这个数值可能与数据库中被(最后一条SQL语句)影响了的“行”数有关,也可能没有。一个大批量HQL操作可能导致多条实际的SQL语句被执行, 举个例子,对joined-subclass映射方式的类进行的此类操作。这个返回值代表了实际被语句影响了的记录数量。在那个joined-subclass的例子中, 对一个子类的删除实际上可能不仅仅会删除子类映射到的表而且会影响“根”表,还有可能影响与之有继承关系的joined-subclass映射方式的子类的表。
注意,上述大批量HQL操作的少数限制会在新版本中得到改进;进一步详细信息请参考JIRA里的路线图(roadmap)。
分享到:
相关推荐
这个"File-batch-processing-module.rar"压缩包显然包含了用于实现文件批量处理功能的代码或工具。让我们深入探讨一下批量处理的概念、重要性以及它可能包含的组件。 批量处理,顾名思义,是计算机系统中对大量数据...
《gs-batch-processing-master2:批量处理指南与快速入门》 在IT行业中,批量处理(Batch Processing)是一种常见的数据处理方式,特别是在大数据分析、系统维护和自动化任务执行等领域。"gs-batch-processing-...
总结,"gs-batch-processing3.0.7"是学习和实践Spring Batch的绝佳起点,通过这个示例,开发者能深入理解Spring Batch的工作原理和最佳实践,从而在实际项目中游刃有余地处理各种批量处理挑战。
这个名为"ENVI_Raster_Processing_Batch_Tools_V5.3_18_S1.zip"的压缩包,显然包含了ENVI的批量处理工具的版本5.3.18,可能是一个特定的更新或服务包1。在遥感图像处理领域,批量处理工具是提高工作效率的关键,尤其...
在IT行业中,批量处理是一项非常重要的技能,尤其是在处理大量数据或文件时。批量读取文件是一种有效的方法,能够显著提高工作效率,避免手动操作的繁琐。本文将深入探讨批量读取文件的概念、方法以及如何实现这一...
在这个名为 "springboot-batch-processing" 的压缩包中,很显然,我们有一个使用SpringBoot整合SpringBatch的示例项目,旨在帮助开发者快速理解和应用SpringBatch进行批量数据处理。 首先,让我们了解SpringBatch的...
对于大数据量,Spring Batch 提供了分步处理(Chunk-Oriented Processing)和分割(Partitioning)策略。分步处理将数据分块处理,避免一次性加载过多数据。分割则将大任务分解为子任务,可以并行执行,提升处理速度...
"Time-series Data Processing.zip"这个压缩包显然包含了针对时间序列数据的一系列处理工具,尤其关注于云处理、批量计算以及掩膜处理。 时间序列数据指的是按照时间顺序收集的数据,通常用于追踪和分析随时间变化...
本压缩包"Batch-processing-command.rar"似乎包含了一个名为"Batch processing command.bat"的批处理脚本,旨在帮助用户批量检测硬件信息。下面我们将深入探讨批处理的基本概念、硬件信息检测以及如何使用批处理脚本...
Spring Batch 是一个强大的、全面的批处理框架,由 Spring 社区开发,旨在简化企业级应用中的批量数据处理任务。这个框架提供了一种标准的方式来处理大量的数据输入和输出,使得开发者能够专注于业务逻辑,而不是...
该方法针对批量处理具有相同表格结构的图像进行设计,常用于将识别的文字内容正确地放置回原始的表格结构中。 在引言部分提到,使用光学字符识别(OCR)技术对现有文档进行数字化已经是一个挑战,而如何将识别出的...
批量处理(Batch Processing)是计算机程序设计中的一种策略,尤其是在大数据和机器学习中。它涉及一次性处理多个输入数据样本,而不是逐个处理。批量处理可以极大地提高计算效率,因为它减少了数据读取和写入的开销...
您的应用程序中没有足够的堆空间来同时处理它们,因此您想一次“批量处理”它们,每次处理1,000个。 解决方案 使用Aerospike scanAll()方法扫描整个名称空间或名称空间并进行设置。 每条记录一次从一个缓冲队列中...
一个基于Spring Boot和Spring Batch的批量处理系统是一个高效地处理大量数据的应用框架。Spring Batch是Spring框架的一个模块,专门用于处理批处理任务,而Spring Boot则简化了创建独立的、生产级别的基于Spring的...
6. **Chunk-oriented Processing**: Spring Batch 提供的一种处理策略,将数据分块读取、处理和写入,以提高效率和性能。 在Spring Batch Learning实例中,你可以期待学习到如何定义和配置这些组件。例如,使用XML...
6. **Chunk-Oriented Processing**:Spring Batch 提供了一种基于chunk的处理模式,它在每次事务中处理一定数量的数据块,以提高性能和可恢复性。 7. **JobRepository**:这是Spring Batch中的持久化层,用于存储...
envi扩展插件 批量正射校正(全色/多光谱) 批量图像融合(GS/NND,自动根据文件名匹配多光谱...批量波段运算(支持对文件处理) 批量将加载在视图中的栅格图层输出为字节型TIFF文件 批量格式转换 批量设置忽略值
7. **Batch Processing**:Python的for循环和函数可以用于实现批处理。通过定义一个处理单个文件的函数,然后对文件列表进行迭代,可以批量处理多个空间数据文件。 8. **Geospatial Python脚本**:编写Python脚本...
Spark是由Apache基金会开发的一个开源分布式计算系统,其设计目标是提供一个通用的并行编程模型,支持实时流处理、批量处理和交互式数据分析。与Hadoop MapReduce相比,Spark提供了更高的内存计算性能,降低了数据I/...
- **Spring Batch** 的核心优势在于它能够简化复杂的批量数据处理逻辑,并且通过其内置的功能模块来提高系统的可维护性和可扩展性。 #### 知识点二:Spring Batch 的主要概念 - **Job**:在 Spring Batch 中,一个...