首页 Java java教程 Hibernate中对象的三种状态及相互转化

Hibernate中对象的三种状态及相互转化

Mar 02, 2017 am 11:22 AM

hibernate中的对象有三种状态: 瞬时状态 (Transient),持久状态 (Persistent),脱管状态(Detached)

 1. 瞬时状态 (Transient)

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

 Customer customer=new Customer(“zx”,27,images);
登录后复制

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

瞬时对象特点:

(1) 不和 Session 实例关联

(2) 在数据库中没有和瞬时对象关联的记录

2. 持久状态 (Persistent)

持久化对象就是已经被保存进数据库的实体对象,并且这个实体对象现在还处于Hibernate的缓存管理之中。这是对该实体对象的任何修改,都会在清理缓存时同步到数据库中。如下所示:

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.update()方法来保存更新,但是对实体对象的修改还是会同步更新到数据库中,因为此时customer对象通过save方法保存进数据库后,已经是持久化对象了,然后通过load方法再次加载它,它仍然是持久化对象,所以它还处于Hibernate缓存的管理之中,这时当执行tx.commit()方法时,Hibernate会自动清理缓存,并且自动将持久化对象的属性变化同步到到数据库中。

持久的实例在数据库中有对应的记录,并拥有一个持久化标识 (identifier).

持久对象总是与 Session 和 Transaction 相关联,在一个 Session 中,对持久对象的改变不会马上对数据库进行变更,而必须在 Transaction 终止,也就是执行 commit() 之后,才在数据库中真正运行 SQL 进行变更,持久对象的状态才会与数据库进行同步。在同步之前的持久对象称为脏 (dirty) 对象。

瞬时对象转为持久对象:

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

(2) 使用 fine(),get(),load() 和 iterater() 待方法查询到的数据对象,将成为持久化对象。

持久化对象的特点:

(1) 和 Session 实例关联

(2) 在数据库中有和持久对象关联的记录

3. 脱管状态 (Detached)

当一个持久化对象,脱离开Hibernate的缓存管理后,它就处于游离状态,游离对象和自由对象的最大区别在于,游离对象在数据库中可能还存在一条与它对应的记录,只是现在这个游离对象脱离了Hibernate的缓存管理,而自由对象不会在数据库中出现与它对应的数据记录。如下所示:

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 被关闭后,对象就变为脱管对象。对脱管对象的引用依然有效,对象可继续被修改。

脱管对象特点:

(1) 本质上和瞬时对象相同

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

持久对象转为脱管对象:

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

瞬时对象转为持久对象:

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

三种状态相互转化的状态图如下:

Hibernate三种状态

4 .结合 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 语句,可以把映射文件中  标签的 select-before-update 设为 true, 这种会先发送一条 select 语句取得数据库中的值,判断值是否相同,如果相同就不执行 update语句。不过这种做法有一定的缺点,每次 update 语句之前总是要发送一条多余的 select 语句,影响性能。对于偶尔更改的类,设置才是有效的,对于经常要更改的类这样做是影响效率的。

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

 以上就是Hibernate中对象的三种状态及相互转化的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1663
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1263
29
C# 教程
1237
24
使用PHP的json_encode()函数将数组或对象转换为JSON字符串 使用PHP的json_encode()函数将数组或对象转换为JSON字符串 Nov 03, 2023 pm 03:30 PM

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,已经成为Web应用程序之间数据交换的常用格式。PHP的json_encode()函数可以将数组或对象转换为JSON字符串。本文将介绍如何使用PHP的json_encode()函数,包括语法、参数、返回值以及具体的示例。语法json_encode()函数的语法如下:st

使用Python的__contains__()函数定义对象的包含操作 使用Python的__contains__()函数定义对象的包含操作 Aug 22, 2023 pm 04:23 PM

使用Python的__contains__()函数定义对象的包含操作Python是一种简洁而强大的编程语言,提供了许多强大的功能来处理各种类型的数据。其中之一是通过定义__contains__()函数来实现对象的包含操作。本文将介绍如何使用__contains__()函数来定义对象的包含操作,并且给出一些示例代码。__contains__()函数是Pytho

如何将 MySQL 查询结果数组转换为对象? 如何将 MySQL 查询结果数组转换为对象? Apr 29, 2024 pm 01:09 PM

将MySQL查询结果数组转换为对象的方法如下:创建一个空对象数组。循环结果数组并为每一行创建一个新的对象。使用foreach循环将每一行的键值对赋给新对象的相应属性。将新对象添加到对象数组中。关闭数据库连接。

源码探秘:Python 中对象是如何被调用的? 源码探秘:Python 中对象是如何被调用的? May 11, 2023 am 11:46 AM

楔子我们知道对象被创建,主要有两种方式,一种是通过Python/CAPI,另一种是通过调用类型对象。对于内置类型的实例对象而言,这两种方式都是支持的,比如列表,我们即可以通过[]创建,也可以通过list(),前者是Python/CAPI,后者是调用类型对象。但对于自定义类的实例对象而言,我们只能通过调用类型对象的方式来创建。而一个对象如果可以被调用,那么这个对象就是callable,否则就不是callable。而决定一个对象是不是callable,就取决于其对应的类型对象中是否定义了某个方法。如

使用Python的__le__()函数定义两个对象的小于等于比较 使用Python的__le__()函数定义两个对象的小于等于比较 Aug 21, 2023 pm 09:29 PM

标题:使用Python的__le__()函数定义两个对象的小于等于比较在Python中,我们可以通过使用特殊方法来定义对象之间的比较操作。其中之一就是__le__()函数,它用于定义小于等于比较。__le__()函数是Python中的一个魔法方法,并且是一种用于实现“小于等于”操作的特殊函数。当我们使用小于等于运算符(<=)比较两个对象时,Python

SpringBoot项目里怎么集成Hibernate SpringBoot项目里怎么集成Hibernate May 18, 2023 am 09:49 AM

在SpringBoot项目中集成Hibernate前言Hibernate是一个流行的ORM(对象关系映射)框架,它可以将Java对象映射到数据库表,从而方便地进行持久化操作。在SpringBoot项目中,集成Hibernate可以帮助我们更轻松地进行数据库操作,本文将介绍如何在SpringBoot项目中集成Hibernate,并提供相应的示例。1.引入依赖在pom.xml文件中引入以下依赖:org.springframework.bootspring-boot-starter-data-jpam

PHP 函数如何返回对象? PHP 函数如何返回对象? Apr 10, 2024 pm 03:18 PM

PHP函数可以通过使用return语句后跟对象实例来返回对象,从而将数据封装到自定义结构中。语法:functionget_object():object{}。这允许创建具有自定义属性和方法的对象,并以对象的形式处理数据。

Java错误:Hibernate错误,如何处理和避免 Java错误:Hibernate错误,如何处理和避免 Jun 25, 2023 am 09:09 AM

Java是一种面向对象编程语言,它被广泛地应用于软件开发领域。Hibernate是一种流行的Java持久化框架,它提供了一种简单且高效的方式来管理Java对象的持久化。然而,开发过程中经常会遇到Hibernate错误,这些错误可能会导致程序的异常终止或者不稳定。如何处理和避免Hibernate错误成为了Java开发者必须掌握的能力。本文将介绍一些常见的Hib

See all articles