hibernate 的缓存使用问题

悬赏:5 发布时间:2008-09-13 提问人:vavi (初级程序员)

<script type="text/javascript"></script>

< > 猎头职位: <script type="text/javascript"></script>上海: 30万起年薪诚聘平台高级架构师
问题描述见:
在测试Hibernate二级缓存的时候
把ehcache.xml和hibernate.cfg.xml里的相关二级缓存的配置  都删掉 ,
直接在hbm.xml中配置 <cache  usage= "read-write "  /> ,
发现查询结果看起来仍是通过缓存来查询的
因为sql没有打印两次

Java代码
  1. package com.vavi.test;
  2. import org.hibernate.Session;
  3. import com.vavi.dao.HibernateSessionFactory;
  4. import com.vavi.pojo.Tuser;
  5. public class Test {
  6. public static void main(String[] args) {
  7. Session sess = HibernateSessionFactory.getCurrentSession();
  8. Tuser user_load = (Tuser) sess.load(com.vavi.pojo.Tuser.class,
  9. new Long(1));
  10. System.out.println(user_load.getName());
  11. sess.close();
  12. sess = HibernateSessionFactory.getCurrentSession();
  13. Tuser user_get = (Tuser) sess.get(com.vavi.pojo.Tuser.class,
  14. new Long(1));
  15. System.out.println(user_get.getName());
  16. sess.close();
  17. }
  18. }
package com.vavi.test;import org.hibernate.Session;import com.vavi.dao.HibernateSessionFactory;
import com.vavi.pojo.Tuser;public class Test {public static void main(String[] args) {Session sess = HibernateSessionFactory.getCurrentSession();Tuser user_load = (Tuser) sess.load(com.vavi.pojo.Tuser.class,new Long(1));System.out.println(user_load.getName());sess.close();sess = HibernateSessionFactory.getCurrentSession();Tuser user_get = (Tuser) sess.get(com.vavi.pojo.Tuser.class,new Long(1));System.out.println(user_get.getName());sess.close();}}

HibernateSessionFactory 是MyEclipse 生成的

问题补充:
package com.vavi.test;
/**
* 结论:Session级别的缓存 仅在当前session 生命期内有效
* 一旦该session关闭 ,再次查询时仍需要访问数据库
*/
import org.hibernate.Session;

import com.vavi.dao.HibernateSessionFactory;
import com.vavi.pojo.Tuser;

public class Test_SessionClose {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Session sess = HibernateSessionFactory.getCurrentSession();
Tuser user_load =(Tuser) sess.load(com.vavi.pojo.Tuser.class, new Long(1));
System.out.println(user_load.getName());
sess.close();

sess = HibernateSessionFactory.getCurrentSession();
Tuser user_get =(Tuser) sess.get(com.vavi.pojo.Tuser.class, new Long(1));
System.out.println(user_get.getName());

sess.close();
}

}

这段代码跟上面的一样
唯一 不同的地方就是 不在 Tuser.hbm.xml 加上  <cache usage="read-write" />
这时候打印的结果是 :
Hibernate: select tuser0_.ID as ID0_, tuser0_.NAME as NAME0_0_, tuser0_.AGE as AGE0_0_ from GHJ.TUSER tuser0_ where tuser0_.ID=?
ghj
Hibernate: select tuser0_.ID as ID0_, tuser0_.NAME as NAME0_0_, tuser0_.AGE as AGE0_0_ from GHJ.TUSER tuser0_ where tuser0_.ID=?
ghj
说明session cache 还是失效了的

按照您的说法
我打印了下 System.out.println("session:"+sess);

这两个程序(加不加  <cache usage="read-write" />
)都是 session:org.hibernate.impl.SessionImpl(<closed>)
根据这个打印结果并不能看出什么

所以关键是 这段话 <cache usage="read-write" />
不太清楚 他到底有什么作用 应该不是 一级缓存 二级缓存 或 查询缓存
最后谢谢您的解答 ^^

问题补充:
多谢gotothework的 回答
你说的这几种策略我也知道
但是关键是加上这段话后 <cache usage="read-write" />
不需要访问数据库 就可以直接出现结果了 (详细描述见上)

而我认为 这个查询结果不是  一级缓存 二级缓存 或 查询缓存 里面的内容
但是如果不是
hibernate 又是如何管理这部分缓存的
抑或还是我的理解有误?
问题补充:
To gotothework :
在调用sess.close()这个方法以前,一级缓存是一直有效的.所以应该是由一级缓存里调用出来的.
当你查询时,会首先从一级缓存中寻找,如果查找不到,还会从二级缓存中寻找,如果还未找到,就会从数据库中查询.

我明白

你见我第二个问题补充,现在问题是 其他配置(二级缓存 查询缓存 都不配置),仅在Tuser.hbm.xml 加上 <cache usage="read-write" />

打印结果表明: 第二次查询结果 没有访问数据库 就直接返回结果了

问题补充:
To gotothework :
在您说的这种情况下
hibernate是使用哪种缓存呢?  一级缓存?
但是如果同样的程序
不在 Tuser.hbm.xml 加上 <cache usage="read-write" />
仍是需要先后访问两次数据库的
所以这段 <cache usage="read-write" />  代码作用很诡异
难道加了这段话就保存了一级缓存的数据?

您说的openSession()
我试了下
同时加上了 sess.contains(user_load) 和hashCode() 这个方法

package com.vavi.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

//import com.vavi.dao.HibernateSessionFactory;
import com.vavi.pojo.Tuser;

public class SFTest {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session sess = sf.openSession();
System.out.println(sess.hashCode());

Tuser user_load = (Tuser) sess.load(com.vavi.pojo.Tuser.class,
new Long(1));
System.out.println("sess.contains user_load? "+sess.contains(user_load));
System.out.println(user_load.getName());
sess.close();
System.out.println("sess.contains user_load? "+sess.contains(user_load));

sess =sf.openSession();
System.out.println(sess.hashCode());

Tuser user_get = (Tuser) sess.get(com.vavi.pojo.Tuser.class,
new Long(1));
System.out.println("sess.contains user_load? "+sess.contains(user_load));
System.out.println("sess.contains user_get? "+sess.contains(user_get));
System.out.println(user_get.getName());

sess.close();
System.out.println("sess.contains user_get? "+sess.contains(user_get));
}

}
打印结果如下:
31966667
sess.contains user_load? true
Hibernate: select tuser0_.ID as ID0_, tuser0_.NAME as NAME0_0_, tuser0_.AGE as AGE0_0_ from GHJ.TUSER tuser0_ where tuser0_.ID=?
ghj
sess.contains user_load? false
22375698
sess.contains user_load? false
sess.contains user_get? true
ghj
sess.contains user_get? false

所以这个现象就比较诡异了
发现sess关闭后,sess.contains(user_load)返回值是false的。
但是仍未查询数据库就获得结果了
问题补充:
哈哈 问题搞定 忘了hibernate 是默认启动二级缓存 以及使用 Cache provider: org.hibernate.cache.EhCacheProvider.
我上述的问题现象其实还是使用Hibernate的 二级缓存的

[main] (SettingsFactory.java:209) - Second-level cache: enabled
INFO [main] (SettingsFactory.java:213) - Query cache: disabled
INFO [main] (SettingsFactory.java:321) - Cache provider: org.hibernate.cache.EhCacheProvider
INFO [main] (SettingsFactory.java:228) - Optimize cache for minimal puts: disabled
INFO [main] (SettingsFactory.java:237) - Structured second-level cache entries: disabled

总结:
1、使用二级缓存的话 仅仅必须在 Tuser.hbm.xml 加上 <cache usage="read-write" />
   其他设置使用的是Hibernate 里面jar包的默认配置文件
   当然如果需要高级应用,那就需要自定义配置文件了
2、对于Hibernate,遇到不明白的问题,建议加上<property name="generate_statistics">true</property>
   并打印debug级别日志
3、Session sess = HibernateSessionFactory.getCurrentSession();  仍是获得新的session 实例的
   同时 一级缓存(Session Cache)是在session.close() 调用后就失效的,跟当前没关系 (不知道理解有没有问题)
4、没有莫名其妙的问题,想起老大对我说的一句公告。 哈哈 ,这就是我中秋节的礼物了 ^^

hibernate 的缓存使用问题 转相关推荐

  1. Hibernate一级缓存

    2019独角兽企业重金招聘Python工程师标准>>> import java.io.Serializable; import org.hibernate.Session; impo ...

  2. Hibernate 所有缓存机制详解

    hibernate提供的一级缓存 hibernate是一个线程对应一个session,一个线程可以看成一个用户.也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和 ...

  3. paip. 提升性能---hibernate的缓存使用 总结

    paip. 提升性能---hibernate的缓存使用 总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog ...

  4. hibernate三级缓存概括

    2019独角兽企业重金招聘Python工程师标准>>> Hibernate三级缓存 一级缓存(session级别缓存): 1.session关闭后,缓存就没了:hibernate发出 ...

  5. Hibernate二级缓存详解

    与Session相对的是,SessionFactory也提供了相应的缓存机制.SessionFactory缓存可以依据功能和目的的不同而划分为内置缓存和外置缓存.  SessionFactory的内置 ...

  6. Hibernate二级缓存的使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  7. hibernate mysql缓存机制_Hibernate的缓存机制

    面试常问到的问题: 首先说下hibernate缓存的作用(即为什么要用缓存机制),然后再具体说说Hibernate中缓存分类情况,最后可以举例: Hibernate缓存的作用: Hibernate是一 ...

  8. Hibernate 二级缓存使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  9. hibernate一级缓存和二级缓存的区别[转]

    缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事 ...

  10. hibernate二级缓存理解

    2019独角兽企业重金招聘Python工程师标准>>> 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对 ...

最新文章

  1. linux 用户java_linux之用户管理
  2. 图像检索:再叙ANN Search
  3. ML之PLiR之LARS:利用LARS算法求解ElasticNet回归类型(包括类别编码+属性重要程度排序)问题(实数值年龄预测)
  4. 教你用100多行写一个数据库(附源码)
  5. 299. Bulls and Cows
  6. Activiti 工作流变量的修改方法
  7. 最新2019年dnf辅助制作视频教程
  8. html在div中数字时钟,在JS+CSS中如何实现滚动数字时钟
  9. win10 labelme 使用记录
  10. MacTeX的使用心得
  11. Google Map API v3 - 设置边界和中心
  12. Latex技巧:LaTex插图命令includegraphics参数详解
  13. 上网行为管理功能概述及实现
  14. 高速破解wifi 使用airolib-ng
  15. 常见的HTT相应状态码
  16. python百钱买百鸡及优化
  17. 笔记本的维修实例(转)
  18. 【渝粤教育】国家开放大学2018年春季 0169-22T工程制图基础 参考试题
  19. PMO体系管理制度实例
  20. 3DMax脚本插件--修改材质贴图名称

热门文章

  1. 重磅:又一女程序员被判 9 个月:因薪酬等问题离职,rm -f * 删库,瘫痪 6 个小时...
  2. 简道云--注册和登陆
  3. python实验室公众号_推荐几个Python与数据分析的公众号
  4. “品、智”双驱 联迪商用APOS智能终端突破30万大关
  5. android 引入苹方字体,html苹方字体
  6. C:L1-047 装睡 (10分)
  7. tensorflow的ckpt文件转为npy文件
  8. .net 中viewstate的原理和使用
  9. ASP.NET之ViewState对象
  10. android 自定义ScrollView实现背景图片伸缩(阻尼效果)