问题的产生:假设一次性需要向数据库中保存一百万条数据1000000,则常规的保存方式为
Session session=null;
Transaction tx=null;
try{
session=this.getHibernateTemplate().getSessionFactory().openSession();
tx=session.beginTransaction();
for(int i=0;i<1000000;i++){
s.save(user);
}
tx.commit();
}finally{
if(session!=null)
session.close();
}
上面的保存方式,会出现问题,因为session在调用save方法的时候不会立即将数据保存到数据库,而是先缓存到session范围的一级缓存中,session关闭时,一级缓存也就消失,会将session中的对象清除,一级缓存需要占用内存,而session不能具体控制自己能够保存多少数据,换句话说,只要session不关闭,那么不管你往session里save多少对象session都不管,这就是说session在没关闭前可以拼命缓存对象,当然缓存对象是要消耗内存的,这样一来,当数据量很大的时候内存就会被消耗完,产生内存溢出,上面的代码就会出现这样的问题,当然也许你机子内存很大很大,运行上面代码没有内存溢出,那么你可以将保存数据的条数增加到千万或者十亿,相信你机子这时候会内存溢出,问题出现了,那么怎样来解决,可以有两种方法:
第一种:代码如下
Session session=null;
Transaction tx=null;
try{
session=this.getHibernateTemplate().getSessionFactory().openSession();
tx=session.beginTransaction();
for(int i=0;i<1000000;i++){
s.save(user);
if(i%50==0){
s.flush();
s.clear();
}
}
tx.commit();
}finally{
if(session!=null)
session.close();
}
相信你发现了这段代码与前面那段代码的不同之处,是多了 if(i%50==0){
s.flush();
s.clear();
}那么接下来就说说加这段代码的作用if(i%50==0)判断每次循环后session是否达到50个对象,这个设置可根据需要自己设定,设置的数字越小则与数据库的交互次数就越多,设置得越大,与数据库的交互次数越少,但是消耗的内存就更多,如果太大同样会内存溢出,因此设置一个合理的大小很重要,当session中达到了设置的对象个数后,调用s.flush();方法,该方法的作用是让session中的对象与数据库同步,也就是说让session数据与数据库中一致,会调用操作数据库的方法,简单地说会执行sql语句,在上例中就是会将50个对象批量插入到数据库来达到一致,数据库插入之后调用s.clear(); 方法,这个方法会清除掉session中的缓存对象,在上面来说就是会清除掉50个对象,将内存释放,因此上面的代码是每到50个对象的时候将数据插入到数据库并将session中的缓存对象清除,所以不会有内存溢出
第二种:
用StatelesssSession接口,它不和一级缓存,二级缓存交互,也不触发任何时间,监听器,拦截器,通过该接口会立刻发送到数据库
StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
session.update(customer);
}
tx.commit();
session.close();
注意在上面的例子中,查询返回的Customer实例立即被脱管(detach)。它们与任何持久化上下文都没有关系。
StatelessSession 接口定义的insert(), update() 和 delete()操作是直接的数据库行级别操作,其结果是立刻执行一条INSERT, UPDATE 或 DELETE 语句。因此,它们的语义和Session 接口定义的save(), saveOrUpdate() 和delete() 操作有很大的不同。
分享到:
相关推荐
博文链接:https://yourenyouyu2008.iteye.com/blog/227988
hibernate的查询方式介绍和hibernate的批处理和连接池配置hibernate
hibernate单音测试 批处理 实例项目 数据库是mysql数据库
高效的进行批量数据的处理方案,留作参考。
qconsp2012_hibernate_efetivo 在QCon SP 2012上的Hibernate Effective讲座中使用的应用程序展示了Hibernate在批处理中的使用。 有关讲座的更多详细信息? 访问。
基本篇重点讲述了数据批处理的核心概念、典型的作业配置、作业步配置,以及Spring Batch框架中经典的三步走策略:数据读、数据处理和数据写,详尽地介绍了如何对CVS格式文件、JSON格式文件、XML文件、数据库和JMS...
提供了查询、更新、批处理、调用、(JTA)事务、数据源管理等功能,可以取代Mybatis、Hibernate作为系统的核心ORM框架。Rexdb提供了工具类风格的接口,不需要编写映射配置,使用简便;同时,它还具备同类框架中最...
hibernate笔记学习笔记 主要内用 :对象持久化,映射,对象状态管理HQL,批处理,级联操作
jboss-batch-api_spec.zip,jsr 352:java平台api类的批处理应用程序
刀批 knife batch是一个很棒的小插件,用于执行命令knife ssh ,但在执行迭代之间以n为一组执行命令。... -B INTEGER定义了最大数量的服务器将被批处理。 -W INTEGER定义了两次执行之间的Hibernate时间。
├ 批处理 (批量移动文章/栏目、批量删除、批量上传图片/附件等) ├ 一键排版 ├ 定时任务 ├ tag自动提取 站点配置 ├ 网站参数配置 ├ 用户注册配置 ├ RSS配置 ├ RSS订阅 ├ TAG管理 ├ 文件上传配置 ...
目录 1. 介绍 6 1.1 目的 6 1.2 范围 6 1.3 定义,缩写词 6 1.4 参考文献 6 ...7.7 HIBERNATE 32 7.8 MYSQL 32 8. 数据视图 32 9. 规模和性能 33 9.1 满足的规模 33 9.2 满足的性能 33 10. 质量 33
本系统主要解决患者在需要就医时的挂号难的问题,以MyEclipse为开发工具,在设计方面采用B/S模式,采用当前最先进、最流行的WEB开发框架和技术之一的SSH框架(Struts + Spring + Hibernate)来完成整个系统的设计,在...
因为是慢慢的收藏..东西有点乱.但希望对大家有帮助 (压缩包共2个) 2包 1.编程学习 2.病毒日志 3.apache-ant 4.apache-tomcat 5.数据库 6.web技术 7.java编程 8.基础知识 ...32.批处理 ...34.Hibernate 35.Htc
因为是慢慢的收藏..只是顺序有点乱.但希望对大家有帮助 (压缩包共2个) 1包 1.编程学习 2.病毒日志 3.apache-ant 4.apache-tomcat 5.数据库 6.web技术 7.java编程 ...32.批处理 ...34.Hibernate 35.Htc
Hibernate.jsp ireport.jsp Java.java Java_exercise.java 练习题 JDBC.java JSP.jsp Servlet.jsp Spring.jsp Struts1.x.jsp Struts2.x.jsp WebService.java Xml.java Linux Shell.sh ubuntu.txt ...
{13.4}批处理模式}{195}{section.13.4} {13.5}分页查询}{196}{section.13.5} {13.5.1}MySQL}{198}{subsection.13.5.1} {13.6}连接池}{199}{section.13.6} {13.6.1}Wrapper}{199}{subsection.13.6.1} {13.7}DAO...
批处理更新 354 二进制大对象BLOB 357 RowSet 新特性 359 JdbcRowSet 360 FilteredRowSet 361 内容总结 363 独立实践 364 第二十一章:XML基础 366 学习目标 366 XML的概念 367 定义XML文档 368 命名冲突 371 使用...
JDBC批处理: addBatch executeBatch Statement PreparedStatement Statement{ 1.获取连接 getConnection(); 2.创建Statement conn.createStatement(); 3.执行sql语句 String sql .... insert delete update ...