hibernate框架中对象的状态

hibernate框架中对象的状态

increment:hibernate先会查询数据最大id值,然后在最大值加1在进行保存操作。
hibernate:select max(id) from t_user;
insert into User(hiredate,id)values(?,?)

native 本地数据库的主键策略。

hibernate对象状态
问题:
问题1: 主键生成策略不同,save操作时发送INSERT语句的时机不同.
* native: 在保存对象时,发送SQL.
* increment:在提交事务时,发送SQL.
问题2: 删除对象的时候,没有立刻发生DELETE语句,而是在提交事务的时候发送的.
问题3: 为什么在事务环境下,通过get方法得到的对象,只要修改了属性值,会发生UPDATE语句.

hibernate执行流程,不能从发送sql角度去理解,应该从对象状态方向去理解。

session方法改变对象什么状态?

1.对象状态
临时状态/瞬时态(transient):
刚刚用new语句创建,没有被持久化,不处于session中。
特点:没有oid,不在session当中

持久化状态(persistent):
已经被持久化,加入到session的缓存中。
特点:有oid,在session当中

脱管态/游离状态(detached):
已经被持久化,但不处于session中。
特点:有oid,不在session当中

删除状态(removed):
对象有关联的ID,并且在Session管理下,但是已经计划被删除。
特点:有oid,在session当中,最终的效果是被删除.
可以不考虑,没有什么意义。

判断规则:
1): 对象是否有OID;———可以理解对象的Id,数据库中的主键id
2): 判断对象是否被Session所管理(在一级缓存中).

2.临时/瞬时状态
没有oid,没有被session管理
1):new语句刚创建了一个对象.
Session session = HibernateUtils.getSession();
User user = new User();
user.setName(“tom3”);
user.setSalary(BigDecimal.valueOf(20000.0));
user.setHiredate(new Date());
//———————–此时的user对象是临时瞬时状态:没有id,不被session管理
//——————主键策略为 native,保存的时候就发送sql语句
//开启事物
session.getTransaction().begin();
System.out.println(“—————–“);
session.save(user);
System.out.println(“——————–“);
//提交事物
session.getTransaction().commit();
session.close();

控制台打印:
	-----------------
	Hibernate: 
		insert 
		into
			t_user
			(uname, usalary, uhiredate) 
		values
			(?, ?, ?)
	--------------------
2)情况2):删除状态的对象,在事务提交之后,对象处于临时状态.
  临时状态是没有ID的,测试可以打印该对象的ID,发现存在ID.
   --->设置hibernate.cfg.xml的属性:use_identifier_rollback=true

3.删除状态
特点:此时有OID,被Session所管理中,
但是最终会被删除(我们不关心删除状态的对象).
删除状态的对象必须等到session刷新(flush),
事务提交时才真正从数据库中删除
1)游离状态到删除状态
游离状态:有oid,不被session管理
//游离状态—>删除状态
User u = new User();
u.setId(1L);
//————–此时对象状态为游离托管状态:有id,没被session管理
Session session = HibernateUtils.getSession();
session.getTransaction().begin();

	session.delete(u);// 对象状态为删除状态-----删除的时候在事物提交的时候才发送sql
	System.out.println("-----------------");
	session.getTransaction().commit();
	System.out.println("-------------------");

	控制台打印:
		-----------------
		Hibernate: 
			delete 
			from
				t_user 
			where
				uid=?
		-------------------

2)持久状态编程删除状态

	Session session = HibernateUtils.getSession();
	User user = (User) session.get(User.class, 6L);//持久状态,有id、被session管理
	
	session.getTransaction().begin();
	
	session.delete(user);
	System.out.println("-------------------");
	session.getTransaction().commit();
	System.out.println("-------------------");

	控制台打印:
		Hibernate: 
			select
				user0_.uid as uid1_0_0_,
				user0_.uname as uname2_0_0_,
				user0_.usalary as usalary3_0_0_,
				user0_.uhiredate as uhiredat4_0_0_ 
			from
				t_user user0_ 
			where
				user0_.uid=?
		-------------------
		Hibernate: 
			delete 
			from
				t_user 
			where
				uid=?
		-------------------

4.持久化状态):特点:有OID,被Session所管理(在一级缓存中).
情况1)调用save方法把临时状态变为持久状态
情况2)调用save方法把游离托管状态状态变为持久对象
保存一个对象之后,提交事务/关闭Session,此时对象处于游离状态,
再创建新的Session来保存该对象.
情况3):get和load方法返回的是持久化对象.
情况4):Query.list方法返回的是持久化对象,在处理大数据量的时候,
需要及时清理一级缓存(分页查询).
情况5):update方法把游离对象变成持久化对象.

5.Detached(游离状态/托管状态):特点:有OID,但是不被Session所管理(不在一级缓存中).
情况1):session.close()方法把所有的持久化对象变成游离对象.
情况2):session.clear()方法把所有持久化对象变成游离对象.
情况3):session.evivt(Object)方法把制定的持久化对象变成游离对象.
情况4):使用new创建对象,并设置OID(数据库存在该ID):临时状态–>游离状态;

总结:
new出来的对象—–>临时状态—save()/saveorupdate()/persist()—->持久状态

  ------get()/query/iteratro/load-----> 持久对象----close()/clear()/evict()--------------> 游离状态
		                                      <--save()/saveorupdate()/update()/merge()----
   
   
   
   持久状态-----delete()---->删除状态
							 /
							/
   游离状态-----delete()----

1:save方法只需要把对象从临时变成持久化状态,只需要找到OID即可.不同的ID生成策略,

2: 因为delete方法仅仅只是把游离对象或持久化对象变成删除状态,并不负责发生SQL.
session中的方法仅仅是改变对象的状态,不发SQL:

3: 持久化对象的属性真正发生改变时,才会发生UPDAE语句.


发生SQL的时机:
默认情况下,在事务提交时,会自动去数据库同步这一次对象变化对应的SQL.
事务提交的时候,到底发送了什么SQL?
1:临时状态–>持久化状态:发送INSERT.
2:持久化状态/游离状态—>删除状态:发送DELETE.
3:游离状态–>持久化状态:发送SQL(可能是INSERT或UPDATE).
4:脏的持久化对象同步到数据库.(session快照)
5:session.flush()方法可以手动同步数据库.

总结:由session的持久化方法修改对象的状态,
在同步session数据的时候(默认是提交事务,也可以是flush),
session再同步脏数据(一级缓存和一级快照中数据是否一致,不一致发送sql,)到数据库,完成内存对象和数据库的同步.

 session方法负责改变状态,事务负责同步数据.
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100799.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 0-1多重背包(单调队列+多重背包)[通俗易懂]

    0-1多重背包(单调队列+多重背包)[通俗易懂]原题链接有 N 种物品和一个容量是 V 的背包。第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。输出最大价值。输入格式第一行两个整数,N,V (0<N≤1000, 0<V≤20000),用空格隔开,分别表示物品种数和背包容积。接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。输出格式输出一个整数,表示最大价值。数据范围0<N≤1

    2022年8月8日
    6
  • TVS二极管SM8S36A,花落谁家?

    TVS二极管SM8S36A,花落谁家?汽车的广泛应用,加速了汽车行业高速发展的同时,也促进了汽车电子行业快速发展。在这个注重智能化和用户体验的时代,汽车所面临的电路保护,诸如汽车总线、USB、CAN总线等,其防护等级越来越高,越来越复杂,同时也越来越严格了。对于汽车电子所需要运用的电路保护器件提出了更高的要求,其中使用最广泛的电路保护元器件之一SM8S系列TVS管,就是最有力的证明,汽车专用型电路防护瞬态电压抑制二极管。采购SM8…

    2022年9月23日
    4
  • ArcGIS二次开发知识点总结

    ArcGIS二次开发知识点总结空间分析定义:空间分析是指分析具有空间坐标或相对位置的数据和过程的理论和方法,是对地理空间现象的定量研究,其目的在于提取并传输空间数据中隐含的空间信息。叠置分析定义:是指将同一坐标系统下不同信息表达的两组或多组专题要素的图层进行叠加,从而产生一个新图层的过程缓冲区分析定义:是指根据分析对象的点、线、面实体,自动建立其周围一定距离的带状区,用以识别这些实体或者主体对邻近对象的辐射范围或者…

    2022年6月30日
    26
  • pytorch-resnet34残差网络理解

    pytorch-resnet34残差网络理解工欲善其事必先利其器,在使用该网络之前要先了解该网络的具体细节,我今天也是第一次查资料,然后加上自己的理解去写这篇学习成长文章。残差模块classResidualBlock(nn.Module):def__init__(self,inchannel,outchannel,stride=1,dowansample=None):super(ResidualBlock,self).__init__()self.left=nn.Sequential

    2025年7月13日
    2
  • vscode设置删除行快捷键[通俗易懂]

    vscode设置删除行快捷键[通俗易懂]开发中习惯的快捷键删除:ctrl+Dvscode的删除快捷键:ctrl+shift+K修改方式:默认ctrl+D被addselectiontonextfindmatch使用,先修改调它的快捷键,如图改为ctrl+shift+alt+D,按回车键保存在修改DeleteLine的快捷键为ctrl+D,按回车键保存完成…

    2022年6月15日
    171
  • 语义分割 实例分割 全景分割_语义分割应用场景

    语义分割 实例分割 全景分割_语义分割应用场景之前看过一篇使用分割思想进行目标检测,所以这里补习下一些分割相关的基础知识。这里重点说下语义分割、实力分割和全景分割的区别。1、semanticsegmentation(语义分割)通常意义上的目标分割指的就是语义分割,图像语义分割,简而言之就是对一张图片上的所有像素点进行分类语义分割(下图左)就是需要区分到图中每一点像素点,而不仅仅是矩形框框住了。但是同一物体的不同实例不需要单独分…

    2022年8月21日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号