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)

相关推荐

  • 春城的意思,《寒食》春城……的意思

    技术春城的意思,《寒食》春城……的意思对皇都春色的陶醉和对盛世承平的歌咏。《寒食》作者春城的意思:韩翎春城无处不飞花,寒食东风御柳斜。日暮汉宫传蜡烛,轻烟散入五侯家。【译文】:春天,长安城处处飘飞着落花;寒食节,东风把御

    生活 2021年10月23日
  • mysql数据库优化的几种方法(mysql数据库的优化技术有哪些)

    技术mysql数据库优化的知识点有哪些小编给大家分享一下mysql数据库优化的知识点有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!mysql数据库优化减少数据访问: 设置合理的字段类型,启用压缩,

    攻略 2021年12月24日
  • 学习笔记 2021.12.9cont

    技术学习笔记 2021.12.9cont 学习笔记 2021.12.9cont2021.12.9
    聚合函数
    常见的聚合函数
    具体的count的使用场景的比较(默认具体字段没有非空的)。这里涉及到更多底层

    礼包 2021年12月10日
  • 用比喻的修辞手法写一句话,用比喻和排比的手法写一句话

    技术用比喻的修辞手法写一句话,用比喻和排比的手法写一句话1、比喻:天边的一弯明月像条小船。 2、排比:不忘初心用比喻的修辞手法写一句话,牢记来时的根;不忘初心,走好现在的路;不忘初心,坚定未来的梦。 1、比喻:喻是一种

    生活 2021年10月22日
  • 查找二叉排序树

    技术查找二叉排序树 查找二叉排序树要求在二叉排序树中查找指定的关键字,并在查找过程中输出查找过程中历经的节点。
    函数接口定义:
    typedef int KeyType; //定义关

    礼包 2021年11月12日
  • 怎么修改MySQL的SQL_MODE

    技术怎么修改MySQL的SQL_MODE这篇文章主要讲解了“怎么修改MySQL的SQL_MODE”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么修改MySQL的SQL_

    攻略 2021年11月5日