Hibernate三种状态的转换示例

技术Hibernate三种状态的转换示例小编给大家分享一下Hibernate三种状态的转换示例,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、遇到的神奇的事情使用jpa操作数据库,当我使用findAl

边肖将分享一些Hibernate三种状态转换的例子。希望大家看完这篇文章后有所收获。我们一起讨论一下吧!

一、遇到的神奇的事情

使用jpa操作数据库,在我使用findAll()方法调查处理了一个list的对象后,我对这个List的实体做了一些操作,没有调用update或者saveOrUpdate方法,但是更改后的数据神奇地保存在了数据库中。

最后,简单粗暴的解决方法是将数据中找到的List复制一份,然后进行操作,然后返回。数据正常,数据库未更新。查找资料后发现jpa是hibernate的封装,底层是hibernate,这是hibernate的持久状态造成的。

二、hibernate 的三种状态

瞬时状态 (Transient)

当我们通过Java的new关键字生成一个实体对象时,这个实体对象处于自由状态,如下所示:

客户客户=新客户(“zx”,27,图片);

此时,客户对象处于自由状态。为什么客户对象处于自由状态?这是因为,此时客户只通过JVM获得了一个内存空间,但是还没有通过Session对象的save()方法保存到数据库中,所以还没有纳入Hibernate的缓存管理,也就是说客户对象还在Hibernate的缓存管理之外自由游荡。所以我们可以看到,free object最大的特点就是数据库中没有与之对应的记录。

瞬时对象特点:

与会话实例不关联

数据库中没有与瞬态对象相关联的记录。

持久状态 (Persistent)

持久对象是已经保存到数据库中的实体对象,这个实体对象仍然在Hibernate的缓存管理中。这是对实体对象的任何修改,当清理缓存时,这些修改将与数据库同步。如下图所示:

客户客户=新客户(“zx”,27,图片);

tx=session . BeginIntrasaction();

session.save(客户);

客户=(客户)会话.加载(客户.类,“1”);

customer . setage(28);

tx.commit();

此时我们并没有显示我们调用了session.update()方法来保存更新,而是将实体对象的修改同步更新到数据库中,因为此时客户对象通过save方法保存到数据库中之后,已经是一个持久对象了,再通过load方法重新加载,仍然是一个持久对象,所以还是在Hibernate cache的管理下。此时,当执行tx.commit()方法时,Hibernate将自动清理缓存,并将持久对象的属性更改自动同步到数据库。

的持久性实例在数据库中有相应的记录,并有一个持久性标识符。

持久对象总是与会话和事务相关联。在Session中,对持久对象的更改不会立即改变数据库,只有在Transaction终止后,即执行commit()后,才能真正在数据库中运行SQL进行更改,持久对象的状态才会与数据库同步。同步前的持久对象称为脏对象。

瞬时对象转为持久对象:

瞬态对象通过Session的save()和saveOrUpdate()方法与数据库相关联,这个瞬态对象成为一个持久对象。

通过fine(),get(),load()和iterater()方法查询的数据对象将成为持久对象。

持久化对象的特点:

和会话实例。

数据库中有与持久对象相关联的记录。

脱管状态 (Detached)

当持久对象从Hibernate的缓存管理中分离出来时,它处于自由状态。自由对象和自由对象最大的区别是数据库中可能还有对应它的记录,但是现在自由对象和Hibernate分离了。

e的缓存管理,而自由对象不会在数据库中出现与它对应的数据记录。如下所示:

Customer customer=new Customer(“zx”,27,images);

tx=session.beginTransaction();

session.save(customer);

customer=(Customer)session.load(Customer.class,”1”);

customer.setAge(28);

tx.commit();

session.close();

当session关闭后,customer对象就不处于Hibernate的缓存管理之中了,但是此时在数据库中还存在一条与customer对象对应的数据记录,所以此时customer对象处于游离态;

与持久对象关联的 Session 被关闭后,对象就变为脱管对象。对脱管对象的引用依然有效,对象可继续被修改。

脱管对象特点:

  • 本质上和瞬时对象相同

  • 只是比爱瞬时对象多了一个数据库记录标识值 id.

持久对象转为脱管对象:

当执行 close() 或 clear(),evict() 之后,持久对象会变为脱管对象。

瞬时对象转为持久对象:

通过 Session 的 update(),saveOrUpdate() 和 lock() 等方法,把脱管对象变为持久对象。

三、三种状态的转换

Hibernate三种状态的转换示例

四、举例子

结合 save(),update(),saveOrUpdate() 方法说明对象的状态

(1) Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save()或 update() 方法是没有意义的。如:

Student stu = new Strudnet();

 

stu.setCarId(“200234567”);

 

stu.setId(“100”);

 

// 打开 Session, 开启事务

 

session.save(stu);

 

stu.setCardId(“20076548”);

 

session.save(stu); // 无效

 

session.update(stu); // 无效

 

// 提交事务,关闭 Session

(2) update() 方法两种用途重新关联脱管对象为持久化状态对象,显示调用 update() 以更新对象。调用 update() 只为了关联一个脱管对象到持久状态,当对象已经是持久状态时,调用 update() 就没有多大意义了。如:

// 打开 session ,开启事务 

 

stu = (Student)session.get(Student.class,”123456”);

 

stu.setName(“Body”);

 

session.update(stu); // 由于 stu 是持久对象,必然位于 Session 缓冲中,

 

对 stu 所做的变更将 // 被同步到数据库中。所以 update() 是没有意义的,可以不要这句效果一样的。

 

// 提交事务,关闭 Session

 

Hibernate 总是执行 update 语句,不管这个脱管对象在离开 Session 之后有没有更改过,在清理缓存时 Hibernate总是发送一条 update 语句,以确保脱管对象和数据库记录的数据一致,如:

 

Student stu = new Strudnet();

 

stu.setCarId(“1234”);

 

// 打开 Session1, 开启事务

 

session1.save(stu);

 

// 提交事务,关闭 Session1

 

stu.set(“4567”); // 对脱管对象进行更改

 

// 打开 Session2, 开启事务

 

session2.update(stu);

 

// 提交事务,关闭 Session2

注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。

如果希望只有脱管对象改变了, Hibernate 才生成 update 语句,可以把映射文件中 <class> 标签的 select-before-update 设为 true, 这种会先发送一条 select 语句取得数据库中的值,判断值是否相同,如果相同就不执行 update语句。不过这种做法有一定的缺点,每次 update 语句之前总是要发送一条多余的 select 语句,影响性能。对于偶尔更改的类,设置才是有效的,对于经常要更改的类这样做是影响效率的。

(3) saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。

看完了这篇文章,相信你对“Hibernate三种状态的转换示例”有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/136912.html

(0)

相关推荐

  • 抖音粉丝多少钱,抖音真人粉丝多少钱?

    技术抖音粉丝多少钱,抖音真人粉丝多少钱?关于抖音唰赞上热门
    1、其实现在抖音唰赞上热[的确是存在的,但是唰赞上热仅仅只是概率性的,并不是绝对就能够上热门的,所以大家也不需要把所有的希望都寄托于抖音唰赞上热门上。
    2、那么

    测评 2021年10月20日
  • 静默升级oracle的方法步骤是什么

    技术静默升级oracle的方法步骤是什么本篇内容主要讲解“静默升级oracle的方法步骤是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“静默升级oracle的方法步骤是什

    攻略 2021年11月4日
  • c++编译器(c++用什么软件编程)

    技术C++ OpenCV如何模拟实现微信跳一跳小编给大家分享一下C++ OpenCV如何模拟实现微信跳一跳,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!实机演示Gif:思路:获取小黑人的位置,获得目标方

    2021年12月17日
  • 如何使用变分自编码器VAE生成动漫人物形象(鍙樺垎鑷紪鐮佸櫒VAE)

    技术如何使用变分自编码器VAE生成动漫人物形象如何使用变分自编码器VAE生成动漫人物形象,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。变分自

    攻略 2021年12月23日
  • matplotlib如何设置坐标轴标签和间距

    技术matplotlib如何设置坐标轴标签和间距这篇文章给大家分享的是有关matplotlib如何设置坐标轴标签和间距的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。xlim、ylim我们首先来

    攻略 2021年10月31日
  • 微信如何实名认证不绑定银行卡,微信没有银行卡怎么实名认证

    技术微信如何实名认证不绑定银行卡,微信没有银行卡怎么实名认证微信不绑定银行卡也可通过绑定身份证进行实名认证的微信如何实名认证不绑定银行卡,具体操作如下:1、打开手机微信,点击微信页面下方的“我”2、进入我的页面,点击“钱

    生活 2021年10月28日