感谢别人的分享。
Hibernate中大批量处理数据机制
如果我们要保存的数据量十分巨大,海量信息的保存、更新,那么在程序中执行添加、更新方法,如session.save(),Session对象自身开辟的一级缓存会不断消耗,直至内存溢出。因为每save()一个对象都会添加到一级缓存中,数据量太大,绝对会造成内存溢出。那么该怎样解决大批量操作数据呢?
有一种方法就是在每保存指定条数的数据时,先将一级缓存中的数据与数据库同步一下,之后再清空一级缓存,继续保存接下来的数据,依次循环,直至保存完毕。如下代码:
public void savePetInfo() {
// 创建Session对象
Session session = HibernateSessionFactory.getSession(); // 创建PetInfo对象
PetInfo petInfo = new PetInfo(); petInfo.setPetName("灰太狼"); petInfo.setPetLove(100); // 批量保存数据 for (int i=0;i<100000;i++)
{ // 保存
session.save(petInfo);
// 当保存50条之后,将缓存中的数据与数据库同步,之后清空一级缓存
if (i%50==0) {
// 将一级缓存中的数据同步到数据库中 session.flush();
// 清空一级缓存中的数据,这样不至于造成内存溢出 session.clear(); } }
// 创建Transaction对象
Transaction transaction = session.beginTransaction(); // 提交事务
transaction.commit(); // 关闭session
session.close(); }
实际上Hibernate中为我们处理海量信息的操作提供了解决办法,通过StatelessSession接口实现,该接口是一个无状态接口,它不和一级缓存、二级缓存交互,也不出发任何事件、监听器、拦截器,通过该接口的操作会立即发送给数据库,与JDBC功能一样, StatelessSession session = sessionFactory.openStatelessSession();
还有一种方法进行批量操作就是利用Query对象的executeUpdate()方法执行批量更新、删除、增加,它会清除相关联类的二级缓存(利用:sessionFactory.Evict(Class clz)),但是这样会造成级联和乐观锁定出现问题
如果你要执行批量处理并且想要达到一个理想的性能, 那么使用JDBC的批量(batching)功能是至关重要。将JDBC的批量抓取数量(batch size)参数设置到一个合适值 (比如,10-50之间):
hibernate.jdbc.batch_size 20
其实上面设置值和在save保存数据一定数据然后在flush 和 clear 是一个道理。
有时候,这种org.hibernate.SessionException: Session is closed!报错就可能是由于批处理不对引起的.
[size=x-large]Hibernate中批量更新
上面介绍的方法同样适用于批量更新数据,如果需要返回多行数据,可以使用scroll()方法,从而可充分利用服务器端游标所带来的性能优势。下面是进行批量更新的代码片段:
private void testUser()throws Exception
{
//打开Session
Session session = HibernateUtil.currentSession();
//开始事务
Transaction tx = session.beginTransaction();
//查询出User表中的所有记录
ScrollableResults users = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count=0;
//遍历User表中的全部记录
while ( users.next() )
{
User u = (User) users.get(0);
u.setName("新用户名" + count);
//当count为20的倍数时,将更新的结果从Session中flush到数据库
if ( ++count % 20 == 0 )
{
session.flush();
session.clear();
}
}
tx.commit();
HibernateUtil.closeSession();
}
通过这种方式,虽然可以执行批量更新,但效果非常不好。执行效率不高,而且需要先执行数据查询,然后再执行数据更新,并且这种更新将是逐行更新,即每更新一行记录,都需要执行一条update语句,性能非常低下。
为了避免这种情况,Hibernate提供了一种类似于SQL的批量更新和批量删除的HQL语法。
SQL风格的批量更新/删除
Hibernate提供的HQL语句也支持批量的UPDATE和DELETE语法。
批量UPDATE和DELETE语句的语法格式如下:
UPDATE | DELETE FROM? ClassName [WHERE WHERE_CONDITIONS]
关于上面的语法格式有以下四点值得注意:
● 在FROM子句中,FROM关键字是可选的。即完全可以不写FROM关键字。
● 在FROM子句中只能有一个类名,该类名不能有别名。
● 不能在批量HQL语句中使用连接,显式的或隐式的都不行。但可以在WHERE子句中使用子查询。
● 整个WHERE子句是可选的。
假设,需要批量更改User类实例的name属性,可以采用如下代码片段完成:
private void testUser()throws Exception
{
//打开Session
Session session = HibernateUtil.currentSession();
//开始事务
Transaction tx = session.beginTransaction();
//定义批量更新的HQL语句
String hqlUpdate = "update User set name = :newName";
//执行更新
int updatedEntities = session.createQuery( hqlUpdate )
.setString( "newName", "新名字" )
.executeUpdate();
//提交事务
tx.commit();
HibernateUtil.closeSession();
}
从上面代码中可以看出,这种语法非常类似于PreparedStatement的executeUpdate语法。实际上,HQL的这种批量更新就是直接借鉴了SQL语法的UPDATE语句。
注意:使用这种批量更新语法时,通常只需要执行一次SQL的UPDATE语句,就可以完成所有满足条件记录的更新。但也可能需要执行多条UPDATE语句,这是因为有继承映射等特殊情况,例如有一个Person实例,它有Customer的子类实例。当批量更新Person实例时,也需要更新Customer实例。如果采用joined-subclass或union-subclass映射策略,Person和Customer实例保存在不同的表中,因此可能需要多条UPDATE语句。
执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法,下面是一次删除上面全部记录的代码片段:
private void testUser()throws Exception
{
//打开Session实例
Session session = HibernateUtil.currentSession();
//开始事务
Transaction tx = session.beginTransaction();
//定义批量删除的HQL语句
String hqlUpdate = "delete User";
//执行批量删除
int updatedEntities = session.createQuery( hqlUpdate )
.executeUpdate();
//提交事务
tx.commit();
//关闭Session
HibernateUtil.closeSession();
}
由Query.executeUpdate()方法返回一个整型值,该值是受此操作影响的记录数量。实际上,Hibernate的底层操作是通过JDBC完成的。因此,如果有批量的UPDATE或DELETE操作被转换成多条UPDATE或DELETE语句,该方法返回的是最后一条SQL语句影响的记录行数。
[/size]
分享到:
相关推荐
在处理海量数据时,Hibernate作为一款强大的ORM框架,其默认机制并不适合直接处理大量记录,因为这可能导致内存消耗过大和性能下降。以下是针对Hibernate批量处理海量数据的一些关键知识点和优化策略: 1. **理解...
1. 大数据处理:对于需要处理海量非结构化数据的应用,如日志分析、推荐系统等,Hibernate OGM能有效简化开发流程。 2. 社交网络:如用户关系图、好友推荐等功能,使用对象图数据库可以更好地表示和处理。 3. 分布式...
在当今的Web应用中,全文检索功能已经成为不可或缺的一部分,尤其是在海量数据的场景下,高效的检索机制对于提升用户体验至关重要。Hibernate Search就是为此目的而生的,它将强大的全文搜索引擎Lucene与ORM框架...
5. **大数据处理**:对于大数据部分,可能涉及Hadoop生态系统,包括MapReduce用于分布式数据处理,HDFS用于存储海量数据,以及可能的Spark进行实时数据分析。 6. **Web前端**:Easymall项目可能使用HTML、CSS、...
为了进一步提升系统的效能,可以考虑引入大数据处理技术,如Hadoop或Spark,以应对海量数据的处理和分析。同时,结合云计算技术,提升系统的可扩展性和弹性,以适应未来可能的增长。此外,增加机器学习算法,实现...
Apache Hadoop和Spark等大数据处理框架大量使用Java,利用其并发处理能力和稳定性处理海量数据。Hadoop的MapReduce编程模型就是用Java实现的,而Spark则提供了一种基于Java API的数据处理方式,使得数据科学家和...
其次,**大数据技术应用**涉及到海量数据的处理和分析,主要关注以下几点: 1. **Hadoop**:分布式存储系统HDFS,MapReduce编程模型,HBase和Hive等数据处理工具。 2. **Spark**:快速计算框架,Spark Core、Spark...
【大数据工程师】是互联网行业中一个至关重要的角色,主要负责处理海量数据的存储、处理和分析。这份简历展示了大数据工程师在不同公司的工作经验和专业技能,涵盖了从数据采集到数据分析的整个流程。 1. **HDFS与...
旅游信息系统是一种基于计算机技术,尤其是网络技术和大数据处理技术,为用户提供个性化旅游信息和服务的平台。在当前信息化时代,网络旅游已成为旅游业发展的重要趋势。本文主要探讨了一款使用Java语言开发的旅游...
这个系统旨在利用Hadoop的强大数据处理能力来处理和分析电子商城中的海量交易数据,同时结合SSH框架实现功能丰富的前端界面和稳定的数据持久化。 首先,Hadoop是Apache基金会开发的一个开源分布式计算框架,其核心...
8. **数据挖掘和仓库**:了解数据挖掘引擎、海量数据处理和数据仓库,这显示了对大数据处理和分析的兴趣和知识。 9. **数据结构与算法**:具备坚实的数据结构基础,这对于高效编程和解决复杂问题至关重要。 10. **...
通过JAVA,开发者可以创建复杂的分布式数据处理应用,处理海量数据。 在并发处理方面,JAVA提供了一套强大的线程管理机制和并发库,如ExecutorService、Future和并发集合,使得开发者能够有效地利用多核处理器资源...
* 海量数据导出、出口报运、装箱业务、Shiro 高级安全框架、工作流 Activiti5 * 购销合同业务、购销合同下货物、出口报运单、装箱单、委托书、发票、财务统计 MyBaties 框架: * MyEclipse 插件的使用 * 项目需求...
- 大数据处理:Hadoop等大数据处理框架大多使用Java开发,利用Java的并发和集合框架处理海量数据。 - 服务器端应用:EJB(Enterprise JavaBeans)提供了一种开发组件化、面向服务的企业级应用模型。 总之,Java...
3. 大数据处理:Hadoop、Spark等大数据处理框架都是用Java编写的,利用Java处理海量数据。 4. 企业级应用:EJB(Enterprise JavaBeans)、JMS(Java消息服务)等技术用于构建分布式、高可用的企业级系统。 5. ...
Hadoop、Spark等基于JAVA的大数据处理框架如何处理海量数据,进行高效的数据分析和挖掘,为业务决策提供支持。这包括了MapReduce编程模型、数据流处理以及分布式存储系统的实现细节。 另外,JAVA在云计算领域的贡献...
JAVA的并发库和大数据处理框架(如Apache Flink或Spark)可以帮助快速处理生产线上的海量数据,提供实时决策支持。 8. **JAVA与设备通讯** 通过JAVA的工业协议库,如JPOS(Java Point Of Sale)或MODBUS-JAVA,...
7. **实时性与大数据处理**:物流信息的实时更新和海量数据处理是挑战之一。Java的Apache Kafka可以实现消息队列,保证数据的实时传输,而Hadoop或Spark等大数据处理框架则能处理大规模的数据分析。 8. **持续集成...
Struts处理MVC模式中的Controller部分,Spring提供全面的依赖注入和AOP支持,Hibernate简化了数据库操作,EJB为企业级应用提供服务,JSP和Servlet用于动态网页生成。面试中可能会要求你解释这些框架的基本原理,或者...