在Hibernate框架中详谈一级缓存
在学习Hibernate的过程中我们肯定会碰上一个名词---缓存,一直都听说缓存机制是Hibernate中的一个难点,它分为好几种,有一级缓存,二级缓存和查询缓存
今天呢,我就跟大家分享分享我所理解的一级缓存
要想完美的体现出缓存机制的话,我想通过查询语句生成的sql应该就能够很清楚的看到
那些Hibernate的配置信息我就不展示了,直接看关键代码
场景:我要查询同一个对象,查询两次,观察在不同的情况下,sql语句的生成情况
我事先准备了一个HibernateUtil工具类,具体如下
package util; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; public class HibernateUtil {
//初始化一个ThreadLocal对象
private static final ThreadLocal sessionTL =new ThreadLocal();
private static Configuration configuration;
private final static SessionFactory sessionFactory;
static {
try{
configuration=new Configuration().configure();
sessionFactory=configuration.buildSessionFactory();
}catch(Throwable ex){
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
} } //获取session
public static Session currentSession(){
Session session=(Session)sessionTL.get();
if(session==null){
session=sessionFactory.openSession();
sessionTL.set(session);
}
return session;
} //关闭session
public static void closeSession(){
Session session= (Session)sessionTL.get();
sessionTL.set(null);
session.close();
}
}
正常我们访问DB端时应该是访问几次就发送几次sql,如下所示
//查询学生信息
public static void select(){ //由班级查询该班级学生信息
Session session=HibernateUtil.currentSession();
Grade grade=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade.getGname());
Grade grade2=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade2.getGname());
}
结果应该是这样

那么问题就来了,我们现在有如下几个场景
场景一:使用同一个session连续查询两次同一个对象
//查询学生信息
public static void select(){ //由班级查询该班级学生信息
Session session=HibernateUtil.currentSession();
Grade grade=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade.getGname());
Grade grade2=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade2.getGname());
}
这个时候我们不难发现,此时我查询的是同一个对象,按照正常理解,我查询了两遍应该向DB端发送两条sql语句才对,下面看看实际的sql数

这个时候可能有的小伙伴就有疑问了,我们后面再解释这种情况,我们先接着看第二种场景
场景二:在第一次查询完毕后,关闭session对象,重新开启一个session然后继续查询同一个对象
//查询学生信息
public static void select(){ //由班级查询该班级学生信息
Session session=HibernateUtil.currentSession();
Grade grade=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade.getGname());
//关闭session
HibernateUtil.closeSession();
//重新获取session
session=HibernateUtil.currentSession();
Grade grade2=(Grade) session.get(Grade.class, );
//输出班级信息
System.out.println(grade2.getGname());
}
这个时候我们查询的任然是同一个对象,结果却如下图

那么,通过以上两个场景的模拟,有些小伙伴可能已经明白是怎么回事了,可能有些小伙伴们还有些迷糊,下面我就讲讲我的看法吧~
总结:1:当我没有关闭session时用的同一个session两次访问同一个对象时,只会向DB端发送一条sql语句
* 原因:因为我第一次访问数据库的时候Hibernate会自动的将我查询出来的结果保留一份查询出来的对象到一级缓存
并且这个额对象是根据OID唯一标识的,也可以理解为数据库中的主键值,然后当我再一次访问一个对象时,Hibernate
机制会自动的先去一级缓存中查找看有没有OID与我要查询的OID相同的对象,如果有的话,则直接从一级缓存中 拿数据
如果没有相同的OID则说明缓存中没有我要的记录,那么就会直接去访问DB端了,这样的话,又会重新发送一条sql
2:当我第一次查询完数据后立即关闭session,这时重新开启一个session来访问同一个对象,这时我们会发现它居然向数据库发送了两条Sql语句。这是为什么呢?
* 原因:其实原因很简单,因为我们虽然说是访问的同一个对象,但是我们随即就关闭了这个session而重新开启了一个session,
此时我们访问时的session是不一致的也就是说是两个不同的session发出的请求,这样理解的话,我们就不难理解了。
所以总结出,一级缓存是一个会话级别的缓存,当一次回话结束后该会话里的缓存则会全部的销毁,所有我们自然就只能重新发送一条sql啦。
在Hibernate框架中详谈一级缓存的更多相关文章
- hibernate框架学习之一级缓存
l缓存是存储数据的临时空间,减少从数据库中查询数据的次数 lHibernate中提供有两种缓存机制 •一级缓存(Hibernate自身携带) •二级缓存(使用外部技术) lHibernate的一级缓存 ...
- Hibernate框架(四)缓存策略+lazy
Hibernate作为和数据库数据打交道的框架,自然会设计到操作数据的效率问题,而对于一些频繁操作的数据,缓存策略就是提高其性能一种重要手段,而Hibernate框架是支持缓存的,而且支持一级和二级两 ...
- hibernate中的一级缓存与闪照区
首先Hibernate中的一级缓存默认是打开的,并且范围从session创建到session关闭,存储的数据必须是持久态的数据. 1 //从session创建开始,一级缓存也跟着创建 2 Sessio ...
- C#开发微信门户及应用(48) - 在微信框架中整合CacheManager 缓存框架
在我们的很多框架或者项目应用中,缓存在一定程度上可以提高程序的响应速度,以及减轻服务器的承载压力,因此在一些地方我们都考虑引入缓存模块,这篇随笔介绍使用开源缓存框架CacheManager来实现数据的 ...
- hibernate框架中注意的几个问题
使用hibernate框架中,session.createSQLQuery创建sql语句的时候遇到的问题 1. select e.id,d.id from emp e,dept d where e. ...
- 关于HttpSession 和 Hibernate框架中 session异同点的简单解析
快速理解: HttpSession中的session是一个容器用来盛基于会话机制的信息. 比喻:我把钱放进银行的保险柜里. 解析:我的钱就是我的信息,ID等 银行的保险柜就是session容器. Hi ...
- 【MyBatis学习12】MyBatis中的一级缓存
缓存的作用是减轻数据库的压力,提高数据库的性能的.mybatis中提供了一级缓存和二级缓存,先来看一下两个缓存的示意图: 从图中可以看出: 一级缓存是SqlSession级别的缓存.在操作数据库时 ...
- 阶段3 1.Mybatis_11.Mybatis的缓存_6 Mybatis中的一级缓存
Mybatis中的一级缓存和二级缓存 一级缓存: 它指的是Mybatis中SqlSession对象的缓存. 当我们执行查询之后,查询的结 ...
- Hibernate中的一级缓存、二级缓存和懒加载(转)
1.为什么使用缓存 hibernate使用缓存减少对数据库的访问次数,从而提升hibernate的执行效率.hibernate中有两种类型的缓存:一级缓存和二级缓存. 2.一级缓存 Hibenate中 ...
随机推荐
- 飞鱼(FlyFish)——便捷的原型在线制作工具
关于项目原型制作,小菜先前写过一篇文章<FastUI快速界面原型制作工具>,只不过那个是用C#写的原型制作工具,但是感觉用C#写起来比较费力,而且也不太好用,经过高人指点,茅塞顿开,决定重 ...
- Swift 和 C# 的语法比较
昨天看到Jacob Leverich 写了一篇文章 Swift is a lot like Scala 介绍Swift 和 Scala 的语法对比,从这篇文章的确可以看到Swift 的语法和 Scal ...
- Module Zero之Nuget包
返回<Module Zero学习目录> ABP module-zero已经发布在了nuget上了.这里是所有的包列表. Abp.Zero module zero的核心包. Abp.Zero ...
- 《Entity Framework 6 Recipes》翻译系列 (5) -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模
2-3 无载荷(with NO Payload)的多对多关系建模 问题 在数据库中,存在通过一张链接表来关联两张表的情况.链接表仅包含连接两张表形成多对多关系的外键,你需要把这两张多对多关系的表导入到 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (12) -----第三章 查询之使用SQL语句
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-2使用原生SQL语句更新 问题 你想在实体框架中使用原生的SQL语句,来更新底层 ...
- Android开发学习之路-该怎么学Android(Service和Activity通信为例)
在大部分地方,比如书本或者学校和培训机构,教学Android的方式都基本类似,就是告诉先上原理方法,然后对着代码讲一下. 但是,这往往不是一个很好的方法,为什么? ① 学生要掌握这个方法的用途,只能通 ...
- 修改windows自带的Ctrl+Space输入法切换快捷键
使用场景: 多为我等码农使用一些编辑器时,编辑器的默认代码提示热键为 ctrl+space ,但这个热键被系统的输入法开关占用.如果遇到可以设置快捷键的编辑器还好,要是不能设置的话(比如火狐浏览器的代 ...
- Atitit事件代理机制原理 基于css class的事件代理
Atitit事件代理机制原理 基于css class的事件代理 1.1. 在javasript中delegate这个词经常出现,看字面的意思,代理.委托1 1.2. 事件代理1 1.3. 代理标准化规 ...
- sublime text3同时编辑多行
sublime text3同时编辑多行 下面的才是正确的姿势,之前一直是shift + 右键 拖啊. http://stackoverflow.com/questions/32127604/how-t ...
- 有吧友需要PDF的下载站点,好吧,我这边汇总一下
[经验]谈谈怎么找自己想要的资源吧~ http://www.cnblogs.com/dunitian/p/4715482.html PDF Free Computer, Programming, Ma ...