简单理解Hibernate三种状态的概念及互相转化 - 笨蛋蜗牛 - 博客园
在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的。对于理解hibernate,JVM和sql的关系有更好的理解。对于需要持久化的J***A对象,在它的生命周期中有三种状态,而且互相转化。
Hibernate三种状态之一:临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;
Hibernate三种状态之二:持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;
Hibernate三种状态之三:游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;
Hibernate三种状态中游离对象和临时对象异同:
两者都不会被Session关联,对象属性和数据库可能不一致;
游离对象由持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;
Hibernate和SQL的关系:
在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;
下面举例说明:
一,Session.save(user)运行机理。 1,把User对象加入缓存中,使它变成持久化对象; 2,选用映射文件指定的标识生成ID; 3,在Session清理缓存时候执行:在底层生成一个insert
sql语句,把对象存入数据库;
注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;
二,Session.delete(user)运行过程。 如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:在Session清理缓存时候; 如果user是游离对象: 1,将user对象和Session关联,使之成为持久化对象; 2,然后按照user
是持久化对象的过程执行;阿里J***A开发面试常问问题总结3-android100学习网
阿里J***A开发面试常问问题总结3
Java集合类Java的集合类都位于java.util包中,Java集合中存放的是对象的引用,而非对象本身。Java集合主要分为三种类型:1.Set(集):集合中的对象不按特定方式排序,...
Java集合类
Java的集合类都位于java.util包中,Java集合中存放的是对象的引用,而非对象本身。
Java集合主要分为三种类型:
1.Set(集):集合中的对象不按特定方式排序,并且没有重复对象。它的有些实现类能对集合中的对象按特定方式排序。
2.List(列表):集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象。
3.Map(映射):集合中的每一个元素包含一对键对象和值对象,集合中没有重复的键对象,值对象可以重复。它的有些实现类能对集合中的键对象进行排序。
Set、List和Map统称为Java集合。
List和Set都继承Collection接口,而Map没有继承Collection接口。
List的主要实现类有:ArrayList类, LinkedList类, Vector类。
Set的主要实现类有:HashSet类,TreeSet类,LinkedHashSet类。
Map的主要实现类有:HashMap类,HashTable类,TreeMap类,WeekHashMap类和IdentityHahMap类等。
set和list的区别
1、List,Set都是继承自Collection接口,均为接口
2、List特点:元素有放入顺序,元素可重复
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
3、List接口有三个实现类:LinkedList,ArrayList,Vector ;
Set接口有两个实现类:HashSet(底层由HashMap实现), LinkedHashSet。
Hibernate中java的对象状态
在Hibernate中,对象有三种状态:临时状态、持久状态和游离状态。
临时状态:当new一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被jre垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save或者SaveOrUpdate把临时对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久对象。
持久状态:持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对象进行delete操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再存在对应关系,持久化对象变成临时状态。持久化对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。
游离状态:当Session进行了Close、Clear或者evict后,持久化对象虽然拥有持久化标识符和与数据库对应记录一致的值,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。
数据库事务的特性
数据库事务(Transaction)是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。一方面,当多个应用程序并发访问数据库时,事务可以在应用程序间提供一个隔离方法,防止互相干扰。另一方面,事务为数据库操作序列提供了一个从失败恢复正常的方法。
事务具有四个特性:原子性(Atomicity)、一致性(Consistency)、隔离型(Isolation)、持久性(Durability),简称ACID。
1 原子性(Atomicity)
事务的原子性是指事务中的操作不可拆分,只允许全部执行或者全部不执行。
2 一致性(Consistency)
事务的一致性是指事务的执行不能破坏数据库的一致性,一致性也称为完整性。一个事务在执行后,数据库必须从一个一致性状态转变为另一个一致性状态。
3 隔离性(Isolation)
事务的隔离性是指并发的事务相互隔离,不能互相干扰。
4 持久性(Durability)
事务的持久性是指事务一旦提交,对数据的状态变更应该被永久保存。
数据库事务隔离级别及锁机制
为了平衡隔离性能,SQL92规范定义了四个事务隔离级别:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)、串行化(Serializable)。四个级别逐渐增强,每个级别解决上个级别的一个问题。
1 读未提交(Read Uncommitted)
另一个事务修改了数据,但尚未提交,而本事务中的select会读到这些未被提交的数据(也称脏读)。
2 读已提交(Read Committed)
本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的select会读到不同的结果(不可重复读)。
不可重复读是指同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。
3 可重复读(Repeatable Read)
在同一个事务里,select的结果是事务开始时间点的状态,同样的select操作读到的结果会是一致的。但是,会有幻读现象。
不可重复读保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会发现了这些新数据,貌似之前读到的数据是幻觉,这就是幻读。
4 串行化(Serializable)
所有事务只能一个接一个串行执行,不能并发。
隔离级别的选择
事务隔离级别越高,越能保证数据的一致性,但对并发性能影响越大,一致性和高性能必须有所取舍或折中。
一般情况下,多数应用程序可以选择将数据库的隔离级别设置为读已提交,这样可以避免脏读,也可以得到不错的并发性能。尽管这个隔离级别会导致不可重复度、幻读,但这种个别场合应用程序可以通过主动加锁进行并发控制。
HTTP报文包含内容
TCP/IP三次握手和四次挥手
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)
Sequence number(顺序号码) Acknowledge number(确认号码)
第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
完成三次握手,主机A与主机B开始传送数据。
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
JVM 分配内存进入以下区域
jvm有效的管理分配到这几个内存区域。
Code section 代码区 包含这个 字节码文件 (byte code)
Stack section (栈区域) 包含 方法(methods) ,局部变量 (Local variables) 和 引用变量( reference variables)
Heap section (堆区域)包含 对象 (也许会包含引用变量(下面的例子中有提到))
Static section (静态区域) 包含 静态数据/ 方法 (Static 数据 和 方法 为 类的方法,隶属于类)
1:当一个方法被调用时, a frame 是被创建在 栈顶。
2:一旦方法完成执行,控制流返回正在调用的方法,stack 中 frame 被 清空(flushed)
3:局部变量是在栈中创建。
4:实例变量在堆中创建, 是对象的一部分,实例变量 依附于对象。
5:引用变量是在栈中创建。
JVM垃圾回收
1.JVM的gc概述
gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。
垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。gc首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。
1)引用计数
引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用以及引用超出范围时,jvm必须适当增减引用数。当某对象的引用数为0时,便可以进行垃圾收集。
2)对象引用遍历
早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
下一步,gc要删除不可到达的对象。删除时,有些gc只是简单的扫描堆栈,删除未标记的对象,并释放它们的内存以生成新的对象,这叫做清除(sweeping)。这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。因此,许多gc可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。
为此,gc需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止,只有gc运行。结果,在响应期间增减了许多混杂请求。另外,更复杂的 gc不断增加或同时运行以减少或者清除应用程序的中断。有的gc使用单线程完成这项工作,有的则采用多线程以增加效率。
2.几种垃圾回收机制
1)标记-清除收集器
这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。
2)标记-压缩收集器
有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。
3)复制收集器
这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,jvm生成的新对象则放在另一半空间中。gc运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
4)增量收集器
增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。
5)分代收集器
这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。jvm生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。
6)并发收集器
并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。
7)并行收集器
并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序的可扩展性。hibernate数据状态以及更改数据状态的方法比较
hibernate数据状态以及更改数据状态的方法比较
发布时间: 4:29:05
编辑:www.fx114.net
本篇文章主要介绍了"hibernate数据状态以及更改数据状态的方法比较",主要涉及到hibernate数据状态以及更改数据状态的方法比较方面的内容,对于hibernate数据状态以及更改数据状态的方法比较感兴趣的同学可以参考一下。
一、hibernate的数据状态
&Hibernate的对象有3种状态,分别为:瞬时态 (Transient)、持久态(Persistent)、脱管态(Detached,也可以称为游离态)。处于持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。
&可根据与DB,SESSION的关联状态来进行判断。
&&&&&&&&&&&&&&&&&& DB&&&&&&&&&&&&& SESSION
&瞬时&&&&&&&&&&& NO&&&&&&&&&&&&&&&&&&& NO
&持久&&&&&&&&&&&& YES&&&&&&&&&&&&&&&&& YES
&脱管&&&&&&&&&&& YES&&&&&&&&&&&&&&&&&& NO
&1、瞬时态
&由new命令开辟内存空间的java对象,
&Person person = new Person(&xxx&, &xx&);
&如果没有变量对该对象进行引用,它将被java虚拟机回收。
&瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
&瞬时对象特点:
&(1) 不和 Session 实例关联
&(2) 在数据库中没有和瞬时对象关联的记录
&(3) 可以被JVM垃圾回收
&2、持久态
&处于该状态的对象在数据库中具有对应的记录,并拥有一个持久化标识。如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。
&当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在HIbernate持久层的管理之下。
&持久对象具有如下特点:
&(1) 和session实例关联;
&(2) 在数据库中有与之关联的记录。
& (3)& 不能被JVM垃圾回收
&3、脱管态
&当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。当脱管对象被重新关联到session上时,并再次转变成持久对象。
&脱管对象拥有数据库的识别值ID,可通过update()、saveOrUpdate()等方法,转变成持久对象。
&脱管对象具有如下特点:
&(1) 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
&(2) 比瞬时对象多了一个数据库记录标识值ID。
二、三种状态之间的转变:
&1、瞬时态====&&持久态
&(1)Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save() 或 update() 方法是没有意义的。
&(2)saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。
&(3)persist()
&(4)replicate() 方法和saveOrUpdate()类似,执行replicate()方法时会引发SQLINSERT或者UPDATE
&(5)update是把一个脱管状态的对象或自由态对象(一定要和一个记录对应)更新到数据库
&2、托管态====&&持久态
&(1)update() 方法两种用途重新关联脱管对象为持久化状态对象,显示调用 update() 以更新对象。调用 update() 只为了关联一个脱管对象到持久状态,当对象已经是持久状态时,调用 update() 就没有多大意义了。
&(2)saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。
&(3)replicate() 方法和saveOrUpdate()类似,执行replicate()方法时会引发SQLINSERT或者UPDATE
&(4)此外还有lock()、merge()方法
&(5)使用 find(),get(),load(),list()和 iterater() 等方法查询到的数据对象都是持久化对象。造成的转变是托管态===&&持久态
&3、持久态===&&托管态
&(1)当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,
&4、持久态===&&瞬时态、游离态
&(1)delete()方法
三、类似方法的比较
&1、persist和save区别
&(1)persist把一个瞬态的实例持久化,但是并&不保证&标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。
&(2)save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert
&2、saveOrUpdate,update和merge区别
&saveOrUpdate,update差不多,所以主要是saveOrUpdate、update与merge进行比较,而使用的主要区别就是session中存在相同持久化标识(identifier)的实例处理方式
&如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
&(1)当我们使用saveOrUpdate或者update的时候,执行完成后,会抛出异常
&org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]
&(2)但当我们使用merge的时候,把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状态还是持久态,而我们提供的A还是自由态
&3、flush和update区别
&(1)update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象//updateSQL
&(2)flush操作的在持久状态的对象。
&默认情况下,一个持久状态的对象的改动(包含set容器)是不需要update的,对持久状态的数据执行update也是没有意义的,如果你更改了对象的值,等待hibernate flush就自动更新或保存到数据库了。hibernate flush发生在以下几种情况中:
&A、调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合
&B、transaction commit的时候(包含了flush)
&4、clear和evcit的区别
&(1)clear完整的、全部的清除session缓存
&(2)evcit(obj)只是把某个特定的持久化对象从session的缓存中清空。
&5、lock和update区别
&(1)update是把一个已经更改过的脱管状态的对象变成持久状态
&(2)lock是把一个没有更改过的脱管状态的对象变成持久状态,
&如果更改持久状态的对象的内容调用lock()方法的操作步骤是:先把未修改的对象从脱管状态变成持久状态--&然后更改持久状态的对象的内容--&最后等待flush或者手动flush,提交的时候会进行脏数据检查
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接: