- 浏览: 239805 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (101)
- js (10)
- java (39)
- HTTP请求:GET与POST方法的区别(转) (1)
- Freemarker 语法规则 (1)
- AJAX级联菜单实例 (1)
- oralce (1)
- myeclipse (5)
- struts (12)
- sql存储过程基础(转) (4)
- JBPM (1)
- mysql (4)
- hibernate (3)
- ibatis (4)
- spring (4)
- 计算机技术 (1)
- nosql (1)
- sqlserver (1)
- servlet (1)
- 拦截器 (1)
- andriod 开发 (1)
- 程序员 (0)
- 多线程 (2)
- Jenkins (1)
- zk (1)
- JPA (2)
最新评论
-
zhangzh888:
怎么下载 啊 都没有看见文件
sftp处理文件 -
wx_hello:
怎么得到文件的属性呢? 比如文件的新建时间
sftp处理文件 -
HappyVeryGood:
“运行时异常(即非受控异常)自动强制执行整个逻辑工作单元的回滚 ...
事物管理,spring事物详解,spring @transactional -
skeely1234:
感谢分享,太帅了
eclipse下修改项目名导致tomcat内发布名不一致的解决方法
网上也有很多关于hibernate的批处理建议,基本上都是一样的,但如果我们的系统设计的比较纯面向对象,这种方案是非常失败的。下面我来讲述下我使用这种方法碰到的问题,然后分析问题的原因,给出我们目前能接受的方案。
传统方案
利用hibernate.jdbc.batch_size参数,session.flush();,session.clear();来释放内存
<hibernate-configuration>
<session-factory>
.........
<property name=” hibernate.jdbc.batch_size”>50</property>
.........
<session-factory>
<hibernate-configuration>
Session session=HibernateUtil.currentSession();
Transatcion tx=session.beginTransaction();
for(int i=0;i<100000;i++)
...{
Student s=new Student();
s.setName(“Paul”);
session.save(s);
if(i%50==0) //以每50个数据作为一个处理单元
...{
session.flush(); //保持与数据库数据的同步
session.clear(); //清除内部缓存的全部数据,及时释放出占用的内存
}
}
tx.commit();
问题
1) 如果Student的某个属性是别的对象,这样.flush()时会去find每一个关联的对象,这样速度是大打折扣了
2) session.clear()是个相当耗时的方法,特别是当缓存中数据量大的时候。Hibernate从来不建议程序调用该方法,由于session是基于线程的,所以当一个请求结束后session占用的内存自然会释放,这种速度可以忽略不计。
上面的问题主要出在问题1)
新的方案
以空间换时间
针对传统方案一一解决
1) 预先批量查出Student关联的属性对象,这样.flush()时就不需要去find了。
一般我们的对象关联都设置为延迟加载,所以循环时才去find,这样性能也是很慢的
有两种办法来解决
1-1】 select h,m 查询多个对象,用List <Object[]>来接收,这样一次就把需要的数据全查到内存中了
1-2】 join fetch,具体参加jpa语言中的join
2) 不调用.clear(),用做够的内存来跑
List <Object[]> addlist=em.createQuery("select h,m from OweTmpVO h,Meter m join fetch m.contract where h.meterid=m.id and h.je<0 and h.cbdate<:date")
.setParameter("date",date)
.getResultList();
System.out.println("--addlist--size:"+addlist.size());
for(Object[] obs:addlist){
Meter meter=(Meter)obs[1];
OweTmpVO oweTmp=(OweTmpVO)obs[0];
Owe newowe=new Owe();
newowe.setId(oweTmp.getOweid());
newowe.setQfdate(oweTmp.getCbdate());
newowe.setQfje(oweTmp.getJe());
newowe.setMeter(meter);
newowe.setXzqh(meter.getXzqh());
OweCustomerInfo oci=new OweCustomerInfo();
oci.setAddress(meter.getAddress());
oci.setId(newowe.getId());
oci.setLxr(meter.getLinkMan().getLxr());
oci.setName(meter.getUsername());
oci.setTel(meter.getLinkMan().getTel());
if (meter.getContract()!=null){
oci.setHbh(meter.getContract().getHbh());
oci.setLxr(meter.getContract().getLinkMan().getLxr());
oci.setName(meter.getContract().getUsername());
oci.setTel(meter.getContract().getLinkMan().getTel());
}
newowe.setCustomerInfo(oci);
em.persist(newowe);
em.remove(oweTmp);
}
需要解决的问题
新的方案需要大量的内存,而虚拟机只能提供1G多的内存,1百万的记录足够让内存溢出。
我们需要将数据分批来处理,比如根据某些条件来限制查出的记录数,或者用分页(一次50万条),还有就是不能让这些分批在同一线程中,在同一线程中就没有分批的意义了(问题同样存在)。我们可以有两种选择
1) 通过页面来手动操作,这样就把每批放到不同的线程中了。但这需要用户参与,一般来说客户不会采取的。
2) 采用异步调用(定时任务),每个任务相当与一个独立的线程,这样就不用考虑session内存释放的问题了。
把每批用一个任务来完成,间隔执行每个任务即可,注意设置任务间隔,尽量保证同一时间只有一个任务在执行,要不内存还是会溢出的。
3)利用ejb来分布式处理,由于ejb可以独立部署,这样就相当于扩大了内存,可以在web层调用多个ejb来不一个大的任务分成多个小的任务来处理。
下面是我们基于seam的异步调用
public void createReportByYear(){
//临时设置session为足够长,与本方案无关
javax.servlet.http.HttpServletRequest request=(HttpServletRequest)javax.faces.context.FacesContext.getCurrentInstance().getExternalContext().getRequest();
int timeout=request.getSession().getMaxInactiveInterval();
request.getSession().setMaxInactiveInterval(60000);
em.createQuery("delete OweYearReport").executeUpdate();
XzqhVO DCQ=getXzqh();
//处理一个区的数据
createReportByYear1(DCQ);
//为每个区的任务设置个开始时间
TimerSchedule timerSchedule0=new TimerSchedule(10l);//马上
TimerSchedule timerSchedule1=new TimerSchedule(1000*60*1l);//一分钟后
TimerSchedule timerSchedule2=new TimerSchedule(1000*60*2l);
TimerSchedule timerSchedule3=new TimerSchedule(1000*60*3l);
TimerSchedule timerSchedule4=new TimerSchedule(1000*60*4l);
TimerSchedule timerSchedule5=new TimerSchedule(1000*60*4l);
TimerSchedule timerSchedule6=new TimerSchedule(1000*60*5l);
//seam中的事件机制,用来启动任务,
events.raiseTimedEvent("createReportByYear_xzqh1", timerSchedule0);
events.raiseTimedEvent("createReportByYear_xzqh2", timerSchedule1);
events.raiseTimedEvent("createReportByYear_xzqh3", timerSchedule2);
events.raiseTimedEvent("createReportByYear_xzqh4", timerSchedule3);
events.raiseTimedEvent("createReportByYear_xzqh5", timerSchedule4);
events.raiseTimedEvent("createReportByYear_xzqh6", timerSchedule5);
events.raiseTimedEvent("createReportByYear_xzqh7", timerSchedule6);
}
//具体任务
@Observer("createReportByYear_xzqh1")
public void createReportByYearXzqh1(){
em.getTransaction().begin();
createReportByYear1(XzqhVO.XCQ);
em.getTransaction().commit();
}
//真正的业务方法,按区来处理
public void createReportByYear1(XzqhVO xzqh){
xzqh=(XzqhVO)DataDictionaryAction.instance().getDataItemById(XzqhVO.class, xzqh.getId());
List<Owe> oweList=em.createQuery("select h from Owe h left join fetch h.meter left join fetch h.customerInfo where h.xzqh=:xzqh order by h.meter")
.setParameter("xzqh", xzqh)
.getResultList();
发表评论
-
习惯的开发错误
2014-09-09 17:25 473在一个包的下面 创建一个test.java 文件 这样一个小 ... -
得到指定年份的所有周末
2014-08-20 18:18 1209/** * 得到指定年份的所有周末 */ publi ... -
对对字符串可能出现报空指针的小问题
2014-04-14 14:42 888今天很是郁闷啊,遇到一个基础的问题比对字符串的两种写法: ... -
Java 单例模式详解(转)
2014-03-26 16:52 830概念: java中单例 ... -
往文件里写入字符串
2014-01-20 13:52 1150package ab; import java.io.Bu ... -
Java数组,去掉重复值、增加、删除数组元素
2014-01-02 14:18 5169import java.util.List; import ... -
java定时器的使用(Timer)
2013-10-14 16:42 2445java定时器的使用(Timer) 2008-02-14 13 ... -
JSch - Java实现的SFTP(文件上传详解篇)(转)
2013-10-14 16:40 3444JSch是Java Secure Channel的缩写。JSc ... -
jvm
2013-09-30 15:03 772网上看到一位javaeye的同志写的文章,感觉总结的比较好,虽 ... -
sftp处理文件
2013-09-30 15:02 8110最近工作涉及sftp处理文件,写了个工具类,代码已经测试。请需 ... -
java BigDecimal的使用和四舍五入及格式规范(精准数据)
2013-06-17 15:37 21578• Java中的简单浮点数类型float和double不能够进 ... -
servlet拦截器代码
2013-03-29 13:45 22501- 实现Servlet.Filter接口 public cl ... -
session 超时的时间设置
2013-03-22 14:47 979为单个Web应用 配置超时时间可以在web.xml中使用< ... -
Calendar 获取日期
2013-01-23 10:44 1334Calendar 获取日期 如果想得到某个星期几是什么日期, ... -
JAVA帮助文档全系列
2013-01-05 11:02 0JAVA帮助文档全系列 JDK1.5 JDK1.6 JD ... -
Cannot create a server using the selected type
2012-08-27 11:02 0eclipse中安装tomcat服务器,报错" Ca ... -
线程池(jdk实现)
2012-07-10 15:01 0Sun在Java5中,对Java线程的类库做了大量的扩展,其中 ... -
遍历集合
2012-06-26 17:28 1073* * To change this template, c ... -
(转)Java 序列化
2012-06-26 14:55 1953当我们需要序列化一个J ... -
权限控制的发散性思维
2012-06-15 17:31 993权限控制的讨论 http://www.iteye.com ...
相关推荐
**标题**: Hibernate批处理技术详解 **描述**: Hibernate作为Java领域广泛应用的对象关系映射(ORM)框架,提供了高效的数据操作接口。在处理大数据量时,批处理技术能显著提升性能,减少数据库交互次数,降低系统...
在IT行业中,Hibernate是一个强大的Java持久化框架,它简化了与关系型数据库的交互,而单元测试则是确保代码质量的重要工具。在这个“hibernate 单元测试批处理代码”项目中,我们将深入探讨如何使用Hibernate进行...
Hibernate作为一种强大的对象关系映射(ORM)框架,提供了多种批量处理的方式以提高数据处理效率。批量处理对于需要在短时间内处理大量数据的应用尤其重要,如批量更新、批量插入或批量删除等场景。 #### 二、批量...
### Hibernate 查询方式与批处理及连接池配置详解 #### 一、Hibernate 查询方式介绍 Hibernate 是一款优秀的 ORM(对象关系映射)框架,它能够极大地简化数据库操作,并提供多种查询方式来满足不同的业务需求。 #...
《Hibernate入门:初识与实践》 ...总之,"hibernate第一个hibernate"项目是一个绝佳的起点,它将引导你了解并掌握Hibernate的基本概念和操作。通过实践,你可以逐步熟悉ORM思想,为后续的Java开发奠定坚实的基础。
一系列PPT文件提供了关于Hibernate的深入学习材料: - "2018-7-27-Hibernate-检索方式.pptx"可能涵盖了Hibernate的多种检索方式,如Query、Criteria、HQL等,以及它们的使用场景和优缺点。 - "04-2018-7-8-Hibernate...
以上就是关于Hibernate中一对一和一对多关联关系的基本知识及其配置示例。理解和熟练应用这些关联关系是提高Java应用程序数据库操作效率的关键。在使用Hibernate时,要灵活运用各种特性,以适应不同场景的需求,同时...
10. **性能优化**: 在处理一对一关联时,需要注意避免N+1查询问题,通过合理使用JOIN查询或批处理可以提升性能。 **文件名称分析** "HibernateORM"这个文件名可能是包含示例代码、配置文件或教程文档的压缩包,...
Hibernate 提供了多种优化手段,如批处理、预加载、缓存配置等,学习如何根据项目需求进行优化,可以显著提高系统性能。 以上只是压缩包中部分可能包含的知识点,实际学习资料可能包括教程文档、示例代码、实战...
标题“菜鸟快速运行第一个hibernate”表明了这是一个针对初学者的教程,旨在帮助他们快速上手并成功运行他们的第一个Hibernate项目。Hibernate是一个强大的Java ORM(对象关系映射)框架,它简化了数据库操作,使得...
以下是一些关于Hibernate3及其核心组件的知识点: 1. **Hibernate3简介**:Hibernate3是Hibernate项目的第三个主要版本,它提供了一种对象关系映射(ORM)解决方案,允许开发人员使用面向对象的编程模型来处理关系...
- 使用批处理、懒加载、预加载、缓存策略等方法来提升Hibernate应用的性能。 - 注意避免N+1查询问题,合理设计实体关系。 11. **其他高级特性** - 自动更新/创建数据库结构、级联操作、事件监听器、拦截器等。 ...
描述中的"hibernate orm框架api中文文档,学习资料,框架详解资料"进一步明确了这些资源的性质,即它们是关于Hibernate ORM框架的API文档、学习教程以及框架的详细解释,都是中文版本,方便中文读者学习。...
10. **增强的性能**:通过延迟加载、批处理和缓存机制,Hibernate能够在不牺牲性能的情况下提供强大的功能。 在Eclipse中使用这些依赖包,你需要按照以下步骤操作: 1. **创建项目**:首先,在Eclipse中创建一个新...
13. **查询优化**:Hibernate提供了SQL生成器,可以根据不同的数据库生成最优的SQL语句,同时支持批处理操作,提高性能。 这个“hibernate_3.2官方开发包”包含了源码、文档、示例等,可以帮助开发者深入了解...
在IT领域,批处理文件(Batch File)是一种在Windows操作系统中使用的简单脚本形式,它允许用户通过一组预先定义的命令来自动化任务执行。在这个特定的案例中,我们有两个批处理文件,`suspend.bat` 和 `sleep.bat`...
例如,第一加载实体时可能会进行全表扫描,可通过二级缓存、预加载、批处理等方式优化。此外,合理选择访问策略、避免N+1查询等问题也对性能有很大影响。 总结,Hibernate简化了Java应用与数据库之间的交互,通过...
14. **性能优化**:文档还会涵盖如何通过批处理、预加载、缓存策略等手段优化Hibernate的性能。 以上只是《Hibernate 3.6 中文 CHM》文档中部分关键知识点的概述。通过深入学习和实践,开发者可以充分利用Hibernate...
Hibernate是一个开源的ORM框架,它为Java开发者提供了一种高效、便捷的方式来管理数据库操作,消除了Java对象与SQL之间的鸿沟。在本书中,作者详细介绍了Hibernate的核心概念、配置、实体管理、数据持久化、查询语言...
一种解决方法是设置JDBC批处理大小,通过`hibernate.jdbc.batch_size`属性,例如将其设置为20。这意味着每处理20个对象,就会执行一次批处理SQL插入。在代码中,我们需要在适当的时候调用`flush()`和`clear()`方法,...