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)

相关推荐

  • assert的用法及注意事项有哪些

    技术assert的用法及注意事项有哪些这篇文章主要介绍“assert的用法及注意事项有哪些”,在日常操作中,相信很多人在assert的用法及注意事项有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望

    攻略 2021年11月3日
  • nginx部署前后端分离项目(spring boot + vue)

    技术nginx部署前后端分离项目(spring boot + vue) nginx部署前后端分离项目(spring boot + vue)部署后端
    spring boot 项目部署到服务器上,我们只需打

    礼包 2021年12月10日
  • Confluence怎么扩展内存

    技术Confluence怎么扩展内存这篇文章主要介绍了Confluence怎么扩展内存,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。背景:Confluen

    攻略 2021年11月17日
  • 只一行Python代码能实现哪些功能

    技术只一行Python代码能实现哪些功能本篇内容主要讲解“只一行Python代码能实现哪些功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“只一行Python代码能实现哪些功

    攻略 2021年11月20日
  • 如何理解解WCF契约应用

    技术如何理解解WCF契约应用本篇文章给大家分享的是有关如何理解解WCF契约应用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。现在我们来具体实现一个WCF契约

    攻略 2021年11月16日
  • 使用SqlBulkCopy时为注意Sqlserver表中使用缺省值的列的示例分析

    技术使用SqlBulkCopy时为注意Sqlserver表中使用缺省值的列的示例分析本篇文章给大家分享的是有关使用SqlBulkCopy时为注意Sqlserver表中使用缺省值的列的示例分析,小编觉得挺实用的,因此分享给

    攻略 2021年12月4日