Hibernate-ORM:06.Hibernate中三种状态
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------
本篇博客主要叙述Hibernate中的三种状态:临时状态(瞬时状态),持久状态,游离状态
commit和flush三种状态间的使用,commit和flush的区别:
saveOrUpdate和merge三种状态间的使用,saveOrUpdate和merge的区别
前方标注一下,用的是mysql数据库,主键生成策略是increment
一,Hibernate-ORM的对象的三种状态:
* Hibernate对象的三种状态
* 1.临时状态(瞬时态)(临时态,自由态)
* 我们通过new关键字创建出一个类的实例对象, 这个对象和hibernate没有任何关系!
* 2.持久状态
* 对象被session管理。就会产生有一个OID(主键标识符)!这个对象和hibernate有关系
* 3.游离状态(托管态)
* 曾经被session管理过!有OID
*和瞬时态的区别在于,是否存在OID!
大话一下:临时状态就是没有关系,就像你和大街上任意一个女孩没有关系,持久状态就是你和她有了联系(男女朋友,结婚),游离状态就是已经分手了(但是有过曾经)
二,一张图揭秘如何进入各个状态的方法:
三,各个状态的小案例:
@Test
/*简单写一下三种状态,和根据这个increment主键生成策咯生成记录
*
*
----------------------------------
Hibernate: select max(tid) from Teacher
----------------------------------
Hibernate: insert into Teacher (name, tid) values (?, ?)
* */
public void t01ThreeStatus01(){
System.out.println("----------------------------------");
Teacher teacher=new Teacher("孟六爱自由");//临时状态(瞬时状态)
session.save(teacher);//持久状态
System.out.println("----------------------------------");
tr.commit();
session.evict(teacher);//游离状态
}
四,commit()和flush():
1.区别:
* commit()和flush()的区别
*
* flush():是缓存清理,把缓存中的数据同步到数据库!但是不会持久化
* commit():在执行的时候,会默认执行flush(),之后会持久化
* flush()在执行的时候会进行缓存清理,在缓存清理的时候,会进行脏检查!
2. 什么是脏检查?
* 在一个对象被session管理的时候,会创建这个对象的快照,
* 我们之后commit的时候,会拿当前的对象信息和之前对象的快照进行对比,
* 如果当前对象的属性发生改变,那么现在的对象就是脏对象!
* 脏对象会被同步到数据库中!
3.对一个持久化状态的commit操作:
@Test
/*
* 写一下commit可以提交属于持久化状态的数据
*
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
Hibernate: update Teacher set name=? where tid=?
* */
public void t02CommitAndFlush01(){
Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
teacher.setName("CommitTest1");
tr.commit();
}
它会在没有update()的情况下也会做修改,并且持久化到数据库
4.对一个持久化状态的flush操作:
@Test
/*
* 写一下flush可以同步到数据库,但是不会持久化
*
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
*
* */
public void t02CommitAndFlush02(){
Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
teacher.setName("flushTest1");
session.flush();
}
它可以同步到数据库,之后执行完毕之后就回滚掉了,不会持久化,我下面一个例子做证明
5.证明flush只是做同步,不是持久化:
@Test
/*
* 测试flush是否真实同步到数据库,
* 排除缓存,看看是否确实持久化到数据库中还是只是同步,一会就回滚
*
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
============================CommitTest1
Hibernate: update Teacher set name=? where tid=?
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
============================flushTest2
* */
public void t02CommitAndFlush03(){
Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
System.out.println("============================"+teacher.getName());/*CommitTest1*/
teacher.setName("flushTest2");
session.flush(); //清理缓存
session.clear(); //清空缓存
teacher=session.get(Teacher.class,3);/*持久化状态*/
System.out.println("============================"+teacher.getName());/*flushTest2*/
}
五,saveOrUpdate()和merge():
1.区别:
最核心的区别:::::::merge()不会改变对象的状态!!!
* save(): 把瞬时态转换成持久态
* update(): 把游离态转换成持久态
* saveOrUpdate():
* 会根据对象是否有OID来判断执行save还是update
* 如果有oid 执行update
* 如果没有oid 执行save
* merge(): 产生的sql语句和saveOrUpdate有点类似,
* 但是!!!!!
* 01.merge不会改变对象的状态
* 02.当我们的对象处于瞬时状态时,会将对象复制一份到session的缓存中,
* 然后执行save方法,执行insert
2.持久化状态下的saveOrUpdate():
@Test
/*
* saveOrUpdate
* 它会改变状态
* 它会根据有没有oid标识(此java对象的状态),来选择执行save还是update
*
* 当是update的时候的案例
*
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
Hibernate: update Teacher set name=? where tid=?
* */
public void t03SaveOrUpdate01(){
Teacher teacher=session.get(Teacher.class,4);/*持久化状态*/
teacher.setName("SaveOrUpdate01");
session.saveOrUpdate(teacher); /*他走的是update*/
tr.commit();
}
3.临时(瞬时)状态下的SaveOrUpdate():
@Test
/*
* saveOrUpdate
* 它会改变状态
* 它会根据有没有oid标识(此java对象的状态),来选择执行save还是update
*
* 当是save的时候的案例
*
Hibernate: select max(tid) from Teacher
Hibernate: insert into Teacher (name, tid) values (?, ?)
*
* */
public void t03SaveOrUpdate02(){
Teacher teacher=new Teacher("王老师66");//临时状态(瞬时状态)
teacher.setName("SaveOrUpdate02");
session.saveOrUpdate(teacher); /*他走的是update*/
tr.commit();
}
4.(临时)瞬时状态下的merge():
@Test
/*
* Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
* 案例一,save
*
Hibernate: select max(tid) from Teacher
Hibernate: insert into Teacher (name, tid) values (?, ?)
* */
public void t04Merge01(){
Teacher teacher=new Teacher("Merge01goodnice");//临时状态(瞬时状态)
teacher.setName("Merge01");
session.merge(teacher); /*他走的是update*/
tr.commit();
}
5.持久化状态下的merger():
@Test
/*
* Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
* 案例二,update
*
Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
Hibernate: update Teacher set name=? where tid=?
* */
public void t04Merge02(){
Teacher teacher=session.get(Teacher.class,4);/*持久化状态*/
teacher.setName("Merge02");
session.merge(teacher); /*他走的是update*/
tr.commit();
}
6.测试merge()是否会改变对象状态(一):
先准备一个临时对象,做merge操作,之后做update()操作,因为update得操作持久化对象,所以,只需要看报不报错就知道merge会不会改变状态
@Test
/*
* Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
* 案例三,他不会改变状态的案例
它会抛异常,因为不是持久化状态的无法用update,虽然他已经进行了插入操作 Hibernate: select max(tid) from Teacher
Hibernate: insert into Teacher (name, tid) values (?, ?) org.hibernate.TransientObjectException: The given object has a null identifier: cn.dawn.day02.entity.Teacher
........
* */
public void t04Merge03(){
Teacher teacher=new Teacher("Merge03");//临时状态(瞬时状态)
session.merge(teacher); /*他走的是save,但是没有改变为持久化状态*/
tr.commit();
session.update(teacher);
tr.commit();
}
报错,所以merge()没有改变对象状态
7.测试merge()是否会改变对象状态(二):
准备一个临时状态的对象,执行俩次merge(),看是发俩条insert还是有update
@Test
/*
* Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
* 案例四,创建一个对象后,merge一次,之后改变他的属性,再marge一次。。。
他会执行俩次save,因为此对象是临时状态,merge不会改变java对象的状态
Hibernate: select max(tid) from Teacher
Hibernate: insert into Teacher (name, tid) values (?, ?)
Hibernate: insert into Teacher (name, tid) values (?, ?)
........
* */
public void t04Merge04(){
Teacher teacher=new Teacher("Merge04");//临时状态(瞬时状态)
session.merge(teacher); /*他走的是save,但是没有改变为持久化状态*/
teacher.setName("Merge04NewValue");
session.merge(teacher);
tr.commit();
}
结论:两条insert,所以merge()不会改变对象状态
作者:晨曦Dawn
转载请注明出处:博客地址:https://www.cnblogs.com/DawnCHENXI/p/9101984.html
如果有错误,请指出!感激不尽!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Hibernate-ORM:06.Hibernate中三种状态的更多相关文章
- Hibernate的工作流程以及三种状态(面试题)
Hibernate的工作流程以及三种状态 部分转载自:http://www.cnblogs.com/fifiyong/p/6390699.html Hibernate的工作流程: 1. 读取并解析配置 ...
- Hibernate(六)__对象的三种状态
瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象. 持久(persistent):数据库中有数据与之对应,当前 ...
- hibernate(二)一级缓存和三种状态解析
序言 前一篇文章知道了什么是hibernate,并且创建了第一个hibernate工程,今天就来先谈谈hibernate的一级缓存和它的三种状态,先要对着两个有一个深刻的了解,才能对后面我要讲解的一对 ...
- Hibernate学习笔记2.5(Hibernate核心开发接口和三种状态)
1.configuration(配置信息管理,产生sessionfactory) sessionfactory管理一系列的连接池 opensession 永远打开新的,需要手动close getcur ...
- Hibernate学习2--对象的三种状态以及映射关系的简单配置
上篇hibernate的博客总体简单梳理了对象持久化的一些思想以及hibernate中对象持久化化的方法,下面说说对象持久化过程的三种状态. 一.hibernate缓存的概念 1.session与缓存 ...
- Hibernate的工作流程以及三种状态
Hibernate的工作流程: 1. 读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3. 打开Sesssion 4.创建事务Transation 5. 持久化操作 6. ...
- Hibernate之对象的三种状态
Hibernate之Java对象的三种状态 一.简述 本博文大部分的思想和内容引子CSND上名为 FG2006 这位大神的文章,连接地址为:http://blog.csdn.net/fg2006/ar ...
- Hibernate 系列 07 - Hibernate中Java对象的三种状态
引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...
- Hibernate中Java对象的三种状态
Hibernate中Java对象的三种 ...
随机推荐
- 小故事学设计模式之Command : (一) 在永和豆浆店
IT的事就是过场多,过场多了就容易忘,所以我们不妨看一个记一个,这也是一个办法,顺便跟同行们学习交流一下)前几天出去拍照,饿到腿软, 回城附近有一家永和豆浆店, 我们决定去那边解决午餐.豆浆店里面还不 ...
- PHP设计模式——工厂模式
<?php /** * 工厂模式 * 提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类的步骤. * * 工厂类用于创建不同类的实例,并将其返回. */ /** * 服务端 ...
- Java运行时异常与一般异常以及错误的异同
Java提供了两类主要的异常:runtime exception和checked exception.checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常.对于这种异常,JAV ...
- java基础知识一览(二)
一.java基础知识 1.一个文件中只能有一个public的类,因为他的类名要求和文件名相同. 2.classpath变量可以设置其它目录下的类. 例如:类文件所在目录是:F:\Javajdk,那么没 ...
- AngularJS 四 服务
AngularJS服务: API: https://docs.angularjs.org/api/ng/service 下面只会介绍几种,需要的话可以去官网查看 AngularJS服务 ...
- C#实现文件上传以及文件下载
public ActionResult Upload() { // var pathUrl = "http://" + Request.Url.Authority; var fil ...
- 解方程(hash,秦九韶算法)
题目描述 已知多项式方程: a0+a1x+a2x2+⋯+anxn=0 求这个方程在 [1,m]内的整数解(n 和 m 均为正整数). 输入输出格式 输入格式: 共 n+2 行. 第一行包含 2个整数 ...
- TiDB集群手动安装
TIDB的安装 TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analytic ...
- 【原创】展开二层嵌套列表(或pd.Series)的几种方法效率对比
转载请注明出处:https://www.cnblogs.com/oceanicstar/p/10248763.html ★二层嵌套列表(或以列表为元素的pd.Series)有以下几种展开方式 (1)列 ...
- jenkins部署记录
环境规划 主机分配 192.168.2.139 : gitlab 192.168.2.141 : jenkins 192.168.2.142 : haproxy01 192.168.2.143 :ha ...