博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HIbernate的一级缓存和快照
阅读量:2442 次
发布时间:2019-05-10

本文共 3937 字,大约阅读时间需要 13 分钟。

什么是Hibernate的一级缓存

       Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象属性的OID值在Hibernate的一级缓存种进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存种取出使用,不会再查询数据库;如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。 H i b e r n a t e 的 一 级 缓 存 的 作 用 就 是 减 少 对 数 据 库 的 访 问 次 数 。 \color{red}{Hibernate的一级缓存的作用就是减少对数据库的访问次数。} Hibernate访

       在Session接口的实现中包含 一 系 列 的 J a v a 集 合 , \color{red}{一系列的Java集合,} Java这些Java集合构成了Session缓存。只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。所以一级缓存也被称为是Session基本的缓存。

Hibernate的一级缓存有如下特点:

  • 当应用程序调用Session接口的save()、update()、saveOrUpdate()时,如果Session缓存中没有相应的对象,Hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去。
  • 当调用Session接口的load()、get()方法,一级Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询的对象,再去数据库中查询对应对象,并添加到一级缓存中。
  • 当调用Session的close()方法时,Session缓存会被清空。

测试一级缓存

配置orm元数据:

测试方法:

package pers.zhang.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.Test;import pers.zhang.domain.Customer;//测试一级缓存public class Demo {
@Test //证明一级缓存存在 public void fun1(){
Configuration conf = new Configuration().configure(); SessionFactory sessionFactory = conf.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer c1 = session.get(Customer.class, 1l); Customer c2 = session.get(Customer.class, 1l); Customer c3 = session.get(Customer.class, 1l); Customer c4 = session.get(Customer.class, 1l); Customer c5 = session.get(Customer.class, 1l); System.out.println(c3==c5);//true tx.commit(); session.close(); }}

运行JUnit测试输出:

Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_linkman as cust_lin6_0_0_,        customer0_.cust_phone as cust_pho7_0_0_,        customer0_.cust_mobile as cust_mob8_0_0_     from        cst_customer customer0_     where        customer0_.cust_id=?true

在以上代码中,第一次执行Session的get()方法获取customer对象时,由于一级缓存中没有数据,所以Hibernate会向数据库发送一条SQL语句,查询id等于1的对象;

当再次调用了Session的get()方法获取customer2对象时,将不会再发送sql语句,这是因为customer2对象是从一级缓存中获取的。
缓存原理如下图:
在这里插入图片描述

一级缓存的内部结构:(快照区)

Customer表如下:

在这里插入图片描述
测试方法:

@Test	//	public void fun2(){
Configuration conf = new Configuration().configure(); SessionFactory sessionFactory = conf.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer c1 = session.get(Customer.class, 1l); c1.setCust_name("百度");//第一次修改客户名 c1.setCust_name("Google");//第二次改回原来的Google tx.commit(); session.close(); }

运行JUnit测试输出:

Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_linkman as cust_lin6_0_0_,        customer0_.cust_phone as cust_pho7_0_0_,        customer0_.cust_mobile as cust_mob8_0_0_     from        cst_customer customer0_     where        customer0_.cust_id=?

为何我们修改了数据却没有打印update的sql语句?因为快照的存在。

在这里插入图片描述

Hibernate向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存, 这 时 会 使 用 O I D 判 断 一 级 缓 存 中 的 对 象 和 快 照 中 的 对 象 是 否 一 致 , 如 果 两 个 对 象 中 的 属 性 发 生 变 化 , 则 执 行 u p d a t e 语 句 , 将 缓 存 的 内 容 同 步 到 数 据 库 中 , 并 更 新 快 照 ; 如 果 一 致 , 则 不 执 行 u p d a t e 语 句 。 \color{red}{这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库中,并更新快照;如果一致,则不执行update语句。} 使OIDupdateupdateHibernate快照的作用就是确保一级缓存中的数据和数据库中的数据一致。

转载地址:http://yjsqb.baihongyu.com/

你可能感兴趣的文章
加密货币钱包提供商_每日新闻摘要:一位加密货币钱包开发者为了保护用户而黑客攻击
查看>>
如何从Facebook迁移到Google+
查看>>
chromebook刷机_每日新闻摘要:Google终止了将Windows引入Chromebook的项目
查看>>
vue alexa:_免费下载:在任何PC上使用Alexa免提
查看>>
2019新闻列表_每日新闻摘要:Google I / O 2019的期望
查看>>
如何修复破坏大照片的Undertow
查看>>
电子书pdf文件网站_如何转换PDF文件以便于阅读电子书
查看>>
如何在PowerPoint中水平翻转图片
查看>>
如何从Excel列表中的Word中创建邮件标签
查看>>
如何在Linux启动时轻松挂载分区
查看>>
outlook 加载配置项_如何禁用Outlook加载项进行故障排除
查看>>
如何导出或删除Outlook.com搜索历史记录
查看>>
dd-wrt固件_如何使用DD-WRT优先安排网络流量
查看>>
如何将您的计算机变成带有病态胡须的增压TiVo
查看>>
如何在Facebook Messenger中启用暗模式
查看>>
如何远程锁定或擦除iOS 5设备
查看>>
如何重命名您的AirPods
查看>>
powerpoint预览_如何添加,删除和重新排列PowerPoint幻灯片
查看>>
询问HTG:旧版键盘支持,禁用URL警告和Windows中的Linux分区
查看>>
激活parallels_如何在Parallels中免费运行macOS Mojave
查看>>