前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hibernate框架中对象的状态

hibernate框架中对象的状态

作者头像
全栈程序员站长
发布2022-06-30 10:32:18
8360
发布2022-06-30 10:32:18
举报
文章被收录于专栏:全栈程序员必看

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语句.

代码语言:javascript
复制
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();

代码语言:javascript
复制
控制台打印:
	-----------------
	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();

代码语言:javascript
复制
	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()—->持久状态

代码语言:javascript
复制
  ------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,)到数据库,完成内存对象和数据库的同步.

代码语言:javascript
复制
 session方法负责改变状态,事务负责同步数据.

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年7月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档