分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

hibernate框架学习笔记5:缓存

发布时间:2023-09-06 01:42责任编辑:胡小海关键词:缓存

缓存不止存在与程序中,电脑硬件乃至于生活中都存在缓存

目的:提高效率

比如IO流读写字节,如果没有缓存,读一字节写一字节,效率低下

hibernate中的一级缓存:提高操作数据库的效率

示例:

抽取的工具类

package utils;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtils { ???private static SessionFactory sf; ???????static{ ???????//1 创建,调用空参构造 ???????Configuration conf = new Configuration().configure(); ???????//2 根据配置信息,创建 SessionFactory对象 ????????sf = conf.buildSessionFactory(); ???} ???????//获得session => 获得全新session ???public static Session openSession(){ ???????????????//3 获得session ???????????????Session session = sf.openSession(); ???????????????????????????????return session; ???????????} ???//获得session => 获得与线程绑定的session ???public static Session getCurrentSession(){ ???????//3 获得session ???????Session session = sf.getCurrentSession(); ???????????????return session; ???} ???}
View Code

测试类:

示例1:

package cache;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.Test;import domain.Customer;import utils.HibernateUtils;//测试一级缓存public class Demo { ???@Test ???//证明一级缓存存在 ???public void fun1(){ ???????//1 获得session ???????Session session = HibernateUtils.openSession(); ???????//2 控制事务 ???????Transaction tx = session.beginTransaction(); ???????//3执行操作 ???????????????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 ???????//4提交事务.关闭资源 ???????tx.commit(); ???????session.close();// 游离|托管 状态, 有id , 没有关联 ???????????????????????//结果(保证数据库中存在主键为1的数据): ???????//这里调用了五次方法,但是只打印一次SQL语句 ???}}

原理:程序第一次调用get方法,hibernate发送SQL语句查询数据库,查询结果以ResulySet对象返回,

hibernate再组装成Customer(实体类对象),存入session缓存对象,对象返回给程序

第二次调用get方法,会先从缓存中查看是否存在id=1的Customer对象,如果有,直接返回缓存中的对象

多次调用原理相同

明显地发现:这里的缓存技术很好地提升了效率

示例2:

 ???@Test ???// ???public void fun2(){ ???????//1 获得session ???????Session session = HibernateUtils.openSession(); ???????//2 控制事务 ???????Transaction tx = session.beginTransaction(); ???????//3执行操作 ???????????????Customer c1 = session.get(Customer.class, 1l); ???????????????c1.setCust_name("哈哈");//4提交事务.关闭资源 ???????tx.commit(); ???????session.close();// 游离|托管 状态, 有id , 没有关联 ???????????????????}

引入了快照的概念

原理:

上边的原理其实有省略,数据库返回结果后,hibernate组装的时候,其实组装了两个对象,

一个放入缓存中,一个放入快照,返回给程序的是缓存对象,程序第一次修改了缓存对象,事务提交,

这时候hibernate比较缓存中的对象和快照,如果有变化,会同步到数据库中,没有变化,什么都不做

这里就提高了效率,不会多次去数据库查询,只需要比对缓存中的对象,减少不必要地SQL查询语句

示例3:

 ???@Test ???//持久化状态对象其实就是放入session缓存中的对象 ???public void fun3(){ ???????//1 获得session ???????Session session = HibernateUtils.openSession(); ???????//2 控制事务 ???????Transaction tx = session.beginTransaction(); ???????//3执行操作 ???????????????Customer c1 = new Customer(); ???????c1.setCust_id(1l);//托管|游离 ???????????????session.update(c1);//c1被放入session缓存了 ???????????????????????Customer c2 = session.get(Customer.class, 1l); ???????????????//4提交事务.关闭资源 ???????tx.commit(); ???????session.close();// 游离|托管 状态, 有id , 没有关联 ???????????????????}

这段代码运行中,打印SQL的UPDATE语句

原因:缓存中不存在快照,c1放入session缓存中对比快照时候必然不一致,而c2这一句调用get方法后,依照上边的原理,才会运行SQL的UPDATE语句

所以,这段代码中真正使hibernate发送SQL语句的是c2这一行

hibernate框架学习笔记5:缓存

原文地址:https://www.cnblogs.com/xuyiqing/p/8449143.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved