在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中 ...
随机推荐
- 自己动手写游戏:Flappy Bird
START:最近闲来无事,看了看一下<C#开发Flappy Bird游戏>的教程,自己也试着做了一下,实现了一个超级简单版(十分简陋)的Flappy Bird,使用的语言是C#,技术采用了 ...
- iOS开发系列--C语言之数组和字符串
概览 数组在C语言中有着特殊的地位,它有很多特性,例如它的存储是连续的,数组的名称就是数组的地址等.而在C语言中是没有String类型的,那么如果要表示一个字符串,就必须使用字符数组.今天主要就介绍如 ...
- [nRF51822] 8、基础实验代码解析大全 · 实验11 - PPI
前一篇分析了前十个基础实验的代码,从这里开始分析后十个~ 一.PPI原理: PPI(Programmable Peripheral Interconnect),中文翻译为可编程外设互连. 在nRF51 ...
- ASP.NET MVC 5 - 给数据模型添加校验器
在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...
- [公告]Senparc.Weixin.MP v14.2.1 升级说明
在Senparc.Weixin.MP v14.2.1中,所有Senparc.Weixin.MP下的Container,命名空间已经从 Senparc.Weixin.MP.CommonAPIs 改为了 ...
- SSH实战 · AJAX异步校验
前台JS代码 /*异步验证用户名的输入格式以及是否存在*/ function CheckUsername(){ /*取到用户名输入框*/ var nametxt = documen ...
- Laravel 5.3 auth中间件底层实现详解
1. 注册认证中间件, 在文件 app/Http/Kernel.php 内完成: protected $routeMiddleware = [ 'auth' => \Illuminate\Aut ...
- 推荐两款简单好用的图片放大jquery插件
一.zoomfiy.js 推荐可以从这里下载 使用说明: 使用该jquery 插件引入该插件的js:zoomfiy.js 或 min引入该插件的css:zoomfiy.css 或 min前后顺序都可j ...
- javascript动画系列第五篇——模拟滚动条
× 目录 [1]原理介绍 [2]数字加减 [3]元素尺寸[4]内容滚动 前面的话 当元素内容溢出元素尺寸范围时,会出现滚动条.但由于滚动条在各浏览器下表现不同,兼容性不好.所以,模拟滚动条也是很常见的 ...
- 「UI 测试自动化selenium」汇总
<selenium 基础之java实现> selenium RC 环境配置 菜鸟学自动化测试(一)----selenium IDE 菜鸟学自动化测试(二)----selenium IDE ...