知道美河 | 上传资料 | VIP申请 | 精品课程 | 资料搜索 | 问题反馈 | 会员手册 | 积分消费 | 积分充值 | 帐号保护
美河学习学习在线赞助VIP

美河学习在线(主站) eimhe.com

 找回密码
 建立账号
查看: 9686|回复: 7

[原创] 关于Hibernate的缓存之Hibernate的一级缓存理解....

[复制链接]
发表于 2007-1-24 01:14:38 | 显示全部楼层 |阅读模式
俺写了二个来小时关于Hibernate的缓存理解....不知怎么的蓝屏了...只好重启..写的东东没保存......好是郁闷呀...

看来下次得先写好再Copy上来....

重新写过...有时间会做详细修改...........

希望来看贴的高手,多多发表一下建议,,你们如何时解缓存???
一级缓存
Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save(),update(),saveorupdate()等方法 及调用查询接口list,filter,iterate时,如session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,
当Session关闭的时候该Session所管理的一级缓存也会立即被清除
Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置

一级缓存采用的是key-value的Map方式来实现的,在缓存实体对象时,对象的主关键字ID是Map的key,实体对象就是对应的值。所以说,一级缓存是以实体对象为单位进行存储的,在访问的时候使用的是主关键字ID
虽然,Hibernate对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过Session中所提供的方法来对一级缓存的管理进行手工干预。Session中所提供的干预方法包括以下两种
●evict() :用于将某个对象从Session的一级缓存中清除
evict()方法适用于以下二种情况:
1)不需要该对象进行同步的数据更新
2)在批量进行更新与删除时,当更新删除每一个对象后,要释对此对象所占用的内存.

●clear() :用于将一级缓存中的所有对象全部清除。</p>

<p class=MsoNormal>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在进行大批量数据一次性更新的时候,会占用非常多的内存来缓存被更新的对象。这时就应该阶段性地调用clear()方法来清空一级缓存中的对象,控制一级缓存的大小,以避免产生内存溢出的情况。
Hibernate大批量更新时缓存的处理方法:
(假设我们user表的age有5000条大于0的记录,)
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Itertaor users=session.find("from User u where u.age>0").itertaor();//HSL语句就不做解释了
while(user.hasNext()){
User user =(User)users.next();
user.setAge(user.getAge()+1);
//将本批插入的对象立即写入数据库并释放内存
session.flush();
session.clear();
}
tx.commit();
session.close();

用Hibernate处理大批数据时..都必须先执行5000次的update语句,然后才能更新5000个user 对象..
这样就影响到了操作上的性能....在项目当我们遇到性能与空间的问题时,,,要以性能为主..这也就是说要牺牲空间

所以程序最好跳过Hibernate API  而直接通过JDBC API来执来...

我们改一下上面的代码:
Session session=SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn =session.connection();
PreparedStatement  pstmt = conn.prepareStatement("update users set age=age+1 "+"where age >0");
pstmt.executeUpdate();
tx.commit();

虽说这是通过JDBC API搞作的..但本质上还是通过Hibernater Transaction的事务这个接口来声明事务的边界的...

其实最好的解决方法就是以创建存储过程,,用底层的数据库运行..这样性能好,速度快....

我就简单的以Oracle数据库为例子.创建一个名为UserUpdate的存储过程...然后在程序中进行调用...
     UserUpdate的存储过程代码:
                      create or  replace procadure UserUpdate(u_age in number) as
                      begin
                                   update users set age=age+1 where age>u_age;
                        end;
   
  下面的是在程序中如何调用我们命名的存储过程
                      Session session =SessionFactory.openSession();
                     Transaction tx =session.beginTransaction();
                     Connection conn=session.connection();
                   String str="{call UserUpdate(?)}";
                   CallableStatement cstmt= conn.prepareCall(str);
                   cstmt.setInt(1,0);
                  cstmt.executeUpdate();
                  tx.commit();
   注意.开源的MySQL中不支持存储过程的..
用JDBC API的好处是这样的..
它不用把大批量的数据事先加载到内存中,然后再进行更新与修改..所以不会消耗大量内存....
(小程序中是看不出什么差别的..当数据的记录达到一定的数据量的时候自然会发现用Hibernate API 与JDBC API的差别)
在一个就是只能一条记录进行批量更新..不像Hibernate中更新每一条的..

不过在很多方面上Hibernate还是很强大的...完全实现了面向对角的思想......HQL的检索也是面向对象的..

这样可以加强如何理解面向对象编程的思想......希望我们一起努力上进....


可算把一级缓存的内容搞的差不多了..
今天就写这么多了..太累了..呵呵..要不是蓝屏....Hibernate 的二级缓存也能简单和大家一起谈一谈......

  很晚了..有时间我会把二级缓存也写一些的.

[ 本帖最后由 j2eelwd 于 2007-1-24 11:32 编辑 ]

评分

1

查看全部评分

发表于 2007-1-24 01:26:30 | 显示全部楼层
发表于 2007-1-24 09:22:05 | 显示全部楼层
坐在板凳上鼓掌。。。。
总结的不错。。。
楼主Hibernate巨猛啊。。。
发表于 2007-1-26 14:07:57 | 显示全部楼层
发表于 2007-1-30 20:30:11 | 显示全部楼层
发表于 2007-3-23 09:00:54 | 显示全部楼层
发表于 2007-3-27 10:04:58 | 显示全部楼层
发表于 2007-3-27 17:52:03 | 显示全部楼层
您需要登录后才可以回帖 登录 | 建立账号

本版积分规则

 
QQ在线咨询

QQ|小黑屋|手机版|Archiver|美河学习在线 ( 浙网备33020302000026号 )

GMT+8, 2025-7-12 10:59

Powered by Discuz!

© 2001-2025 eimhe.com.

快速回复 返回顶部 返回列表