Hibernate(四)之对象状态及一级缓存
一、Hibernate中的对象状态
1.1、瞬时态(临时态)
没有与Hibernate产生关联
与数据库中的记录没有产生关联(有关联就是与数据库中表的id相对应)
获得:一般都只直接创建(new)
瞬时态 转换 持久态
一般操作:save方法、saveOrUpdate
瞬时态 转换 脱管态
一般操作:通过setId方法设置数据
1.2、持久态
Hibernate有关联
对象有id
获得:
查询操作:get、loat、createQuery、createCriteria 等 获得都是持久态【】
执行save之后持久态
执行update之后持久态
持久态 转换 瞬时态
官方规定执行delete() --民间:删除态
持久态 转换 脱管态
session没有记录
session.close () 关闭
session.clear() 清除所有
session.evict(obj) 清除指定的PO对象
1.3、游离态(脱管态)
没有与Hibernate产生关联
对象有ID
获得:
创建、并设置OID的
通过api获得
脱管态 转换 瞬时态
手动去除OID,设置成默认值
脱管态 转换 持久态
一般操作:update()、saveOrUpdate
1.4、在代码中去查看三种状态
1.5、三种状态的相互转换
1.5.1、瞬时转化为持久
注意:如果主键生成策略中value是assigned需要自己指定主键,不指定会报错。
1.5.2、瞬时转化为游离
在数据库中id=1中已经存在有
1.5.3、持久转化为瞬时
方式二:
1.5.4、持久转化为游离
1.5.5、游离转化为瞬时
1.5.6、游离转化为持久
1.6、三种状态有什么用处?
持久状态,我们使用Hibernate主要是为了持久化我们的数据.
对于对象的状态,我们期望我们需要同步到数据库的数据,都被装换成持久状态
持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中.
二、一级缓存
又称为session级别的缓存。当获得一次会话(session),hibernate在session中创建多个集合(map),用于存放操作数据(PO对象),为程序优化服务,
如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用;如果没有再查询数据库。当session关闭时,一级缓存销毁。
在Hibernate中存在两种缓存:一是线程级别的缓存(session缓存)二是进程级别的缓存(二级缓存)
缓存:用来提高效率的
session缓存:就是session对象中存在的缓存,缓存中存在的是(持久化)对象。
2.1、证明session缓存的存在
我们用图形来理解:
2.2、一级缓存快照
在从数据库取数据时,会将数据一式两份,一份作为缓存中的对象,一份作为快照,在session提交时做对比。
快照:与一级缓存一样的存放位置,对一级缓存数据备份。保证数据库的数据与 一级缓存的数据必须一致。如果一级缓存修改了,
在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库。
举例:
我们画图来分析一下:
持久化状态: 本质就是存在缓存中的对象,就是持久化状态.
2.3、感受一级缓存带来的效率
感受一:
从上面这三行代码中,我们u1执行需要执行一条sql语句,我们执行得到u2和u3时,发现不会去再次查询,而是从缓存中找。
感受二:
从上面代码还在那个我们知道,第一个u1中会执行select语句。当事务还没有提交的时候,只会在缓存中进行。
所以总的只会产生两条sql语句。
2.4、一级缓存中的细节问题
问题一:保存对象时,可以使用save方法和persist方法,他们之间有区别吗?
没有区别,功能上是一样的。但persist(持久) 方法 来自于JPA 接口。而save(保存) 方法来自于Hibernate。
问题二:HQL查询是否会使用一级缓存?
HQL不会使用一级缓存.
问题三:HQL语句批量查询时,查询结果是否会进入缓存?
查询结果会放入缓存中
问题四:SQL查询 结果会不会放入1级缓存中?
如果把查询结果封装到对象中,对象会放入一级缓存
问题五:SQL查询 结果会不会放入1级缓存中?
没有把查询结果封装到对象中,对象不会放入一级缓存
问题六:criteria 会将查询结果放入一级缓存. 但是查询不会使用一级缓存. 与Hql查询结论一致.
三、session中的其他API
evict()方法:将缓存中的对象删除
clear()方法:清空一级缓存
refresh方法:刷新,强制刷新缓存中的对象 => (可以用来解决缓存与数据库数据不同步的问题)
flush方法:对比快照,并提交缓存对象
import java.util.List;import org.hibernate.Session; import org.junit.Test;import com.itheima.domain.User; import com.itheima.utils.HibernateUtils; //其他API (大部分都是了解) public class Demo1 {@Test//1. evict 将缓存中的对象移除.//2. clear 清空1级缓存 public void fun1(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u1 = (User) session.get(User.class, 1);session.clear();User u2 = (User) session.get(User.class, 1);//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 }@Test//3 refresh 刷新 => 强制刷新缓存中的对象 => (可以用来解决缓存与数据库数据不同步的问题)public void fun2(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u1 = (User) session.get(User.class, 1);session.refresh(u1); //将缓存中的对象立刻与数据库同步,会再发送一个sql语句//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 }@Test//4 flush 对比快照,并提交缓存对象public void fun3(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u1 = (User) session.get(User.class, 1);//u1.setName("zhangsan"); session.flush();// 立刻提交session缓存中的对象到数据库//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 }@Test// 代理主键=> native//5.1 aveOrUpdate方法//saveOrUpdate 可以同时完成保存或更新操作//主键为空=>save//主键有值=> updatepublic void fun4(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u = new User();u.setId(99);u.setName("jack");u.setPassword("1234");session.saveOrUpdate(u);//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 }// 自然主键=> assigned//5 update 与 saveOrUpdate方法//saveOrUpdate 可以同时完成保存或更新操作//主键为空=> 报错,因为无论是save还是update 都必须指定id//主键有值=> 先会根据主键查询数据库.// 数据库中存在=> 执行update// 数据库中不存在=> 执行insert @Testpublic void fun5(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u = new User();u.setId(88);u.setName("jack01");u.setPassword("1234");session.saveOrUpdate(u);//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 }@Test//在我们使用Hibernate时候,注意要避免出现,两个相同的ID对象.放入一级缓存的情况.public void fun6(){Session session = HibernateUtils.openSession();session.beginTransaction();//------------------------------------------------User u = (User) session.get(User.class, 1);// 持久化,缓存中存在 session.evict(u); // 游离态,缓存中不存在 User u2 = (User) session.get(User.class, 1);// 持久化,缓存中存在 session.update(u); // 将U重新变为持久化状态,缓存中存在//------------------------------------------------ session.getTransaction().commit();session.close(); // 游离状态 } }
testSessionApi
转载于:https://www.cnblogs.com/cxyzyh2017/p/6678517.html
Hibernate(四)之对象状态及一级缓存相关推荐
- Hibernate第七篇【对象状态、一级缓存】
前言 本博文主要讲解Hibernate的细节-->对象的状态和一级缓存- 对象状态 Hibernate中对象的状态: - 临时/瞬时状态 - 持久化状态 - 游离状态 学习Hibernate的对 ...
- Jpa持久对象状态,一级缓存,二级缓存
1JPA持久对象的状态 1.1. 临时状态(transient):瞬时状态 刚刚用new语句创建,没有和entityManager发生关系 没有被持久化,不处于entityManager中.该对象成为 ...
- Hibernate 几种对象状态
Hibernate 中四种对象状态 临时状态(transient):刚用new 语句创建,还没有被持久化,并且不处于Sesssion 的缓存中.处于临时状态 的Java 对象被称为临时对象. 持久化状 ...
- Hibernate开发和对象状态
Hibernate开发和对象状态 Hibernate开发三种方式 1.由Domain object -> mapping->db.(官方推荐) 2.由DB开始,用工具生成mapping和D ...
- Hibernate_2_Hibernate中对象状态及转化_一级缓存_Session详解_HQL/SQL/Criteria_一对多关系_级联操作
Hibernate中的对象状态 在Hibernate中持久化对象具有三种状态: 瞬时态, 持久态, 游离态. 瞬时态: 对象没有与Hibernate产生关联(transient,session中没有缓 ...
- (转)Hibernate的一级缓存
http://blog.csdn.net/yerenyuan_pku/article/details/70148567 Hibernate的一级缓存 Hibernate的一级缓存就是指Session缓 ...
- MyBatis 一级缓存二级缓存详解
相关内容: 架构师系列内容:架构师学习笔记(持续更新) MyBatis 缓存详解 cache 缓存 缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力.跟Hibernat ...
- 浅谈Mybatis的一级缓存和二级缓存
MyBatis的缓存机制 缓存的引入 当我们大量执行重复的查询SQL语句的时候,会频繁的和数据库进行通信,会增加查询时间等影响用户体验的问题,可以通过缓存,以降低网络流量,使网站加载速度更快. MyB ...
- MyBatis一级缓存失效的几种情况
MyBatis一级缓存失效的几种情况 文章目录 MyBatis一级缓存失效的几种情况 1 MyBatis一级缓存概述 2 四种失效的基本情况 3 几种特殊情况 1 MyBatis一级缓存概述 MyBa ...
- Mybatis一级缓存和二级缓存(带测试方法)
目录 相关导读 一.什么是缓存 二.Mabtis一级缓存 (1)测试一级缓存 (2)清空一级缓存 三.Mybatis二级缓存 (1)开启二级缓存 (2)测试二级缓存 相关导读 Mybatis专栏: M ...
最新文章
- Oracle数据库查看表空间是否为自增的
- 在机器学习分类中如何处理训练集中不平衡问题
- 关于android MTK相机L版本,切换屏幕比例后,分辨率随之改变,但重新进入相机后原有分辨率不再生效问题...
- 《四世同堂》金句摘抄(十一)
- 【Python-3.5】Pygal模拟骰子点数,分析结果可视化
- 新型肺炎数据,可以用Excel绘制成3维地图
- Win11怎么卸载软件?Win11彻底卸载软件教程
- 牛腩新闻发布系统总结(四)--知识点滴
- 学生签到系统c代码_C语言之学生管理系统代码(完整)
- SDL Trados 2019 (SR2)的下载和安装
- mysql 遍历json数据结构,mysql存储过程中遍历json数据
- K8S集群中网络通信故障常见问题的排查思路
- 办公技巧分享:如何把PDF转换成Word的5种方法
- 【重磅】Libra Credit 和Uphold 达成战略合作
- mac 我用Mac的这一年
- 【产业互联网周报】外媒:英特尔等公司暂停向俄罗斯发货;阿里云季度营收195亿元;第四范式再次提交上市申请...
- SEO伪原创文章的一些技巧
- unicode gb2312对应表(GB升序)
- 计算体重指数—BMI 牛客网
- 洪荒开局鸿蒙绑定系统,洪荒开局绑定鸿钧
热门文章
- 八、Linux文本编辑器vim/vi
- 二、Linux常用命令——文件处理命令
- js Date 日期函数
- getWriter() has already been called for this response
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-4.动态Sql语句Mybaties SqlProvider...
- 图解SynchronousQueue原理详解-非公平模式
- 使用Mac命令别名,提升工作效率
- MyBatis笔记(一) 最简单的select
- 关于WordCount的作业
- Kloxo重启Web服务