`
youngbean
  • 浏览: 21489 次
  • 来自: ...
社区版块
存档分类
最新评论

持久层3种状态(转)

阅读更多

持久化层的Java对象可处于哪些状态?这些状态有哪些特征?

选自<<精通Hibernate:Java对象持久化技术详解>> 作者:孙卫琴 来源:www.javathinker.org

当应用程序通过new语句创建了一个对象,这个对象的生命周期就开始了,当不再有任何引用变量引用它,这个对象就结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收。对于需要被持久化的Java对象,在它的生命周期中,可处于以下三个状态之一:

(1) 临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
(2) 持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
(3) 游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。

图1为Java对象的完整状态转换图,Session的特定方法触发Java对象由一个状态转换到另一个状态。从图1看出,当Java对象处于临时状态或游离状态,只要不被任何变量引用,就会结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收;当处于持久化状态,由于Session的缓存会引用它,因此它始终处于生命周期中。


临时对象的特征

临时对象具有以下特征:
(1) 不处于Session的缓存中,也可以说,不被任何一个Session实例关联。
(2) 在数据库中没有对应的记录。

在以下情况下,Java对象进入临时状态:
(1) 当通过new语句刚创建了一个Java对象,它处于临时状态,此时不和数据库中的任何记录对应。
(2) Session的delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录;对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从Session的缓存中删除。

持久化对象的特征

持久化对象具有以下特征:
(1) 位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。
(2) 持久化对象和数据库中的相关记录对应。
(3) Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。

Session的许多方法都能够触发Java对象进入持久化状态:
(1) Session的save()方法把临时对象转变为持久化对象。
(2) Session的load()或get()方法返回的对象总是处于持久化状态。
(3) Session的find()方法返回的List集合中存放的都是持久化对象。
(4) Session的update()、saveOrUpdate()和lock()方法使游离对象转变为持久化对象。(nate注:根据hibernate reference的说法当试图用update更新一个持久化对象时会抛异常)
(5)当一个持久化对象关联一个临时对象,在允许级联保存的情况下,Session在清理缓存时会把这个临时对象也转变为持久化对象。

Hibernate保证在同一个Session实例的缓存中,数据库表中的每条记录只对应惟一的持久化对象。例如对于以下代码,共创建了两个Session实例:session1和session2。session1和session2拥有各自的缓存。在session1的缓存中,只会有惟一的OID为1的Customer持久化对象,在session2的缓存中,也只会有惟一的OID为1的Customer持久化对象。因此在内存中共有两个Customer持久化对象,一个属于session1的缓存,一个属于session2的缓存。引用变量a和b都引用session1缓存中的Customer持久化对象,而引用变量c引用session2缓存中的Customer持久化对象:

Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();

Customer a=(Customer)session1.load(Customer.class,new Long(1));
Customer b=(Customer)session1.load(Customer.class,new Long(1));
Customer c=(Customer)session2.load(Customer.class,new Long(1));

System.out.println(a= =b); //true
System.out.println(a= =c); //false

tx1.commit();
tx2.commit();
session1.close();
session2.close();

Java对象的持久化状态是相对于某个具体的Session实例的,以下代码试图使一个Java对象同时被两个Session实例关联:

Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();

Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer对象被session1关联
session2.update(c); //Customer对象被session2关联
c.setName("Jack"); //修改Customer对象的属性

tx1.commit(); //执行update语句
tx2.commit(); //执行update语句
session1.close();
session2.close();

当执行session1的load()方法时,OID为1的Customer对象被加入到session1的缓存中,因此它是session1的持久化对象,此时它还没有被session2关联,因此相对于session2,它处于游离状态。当执行session2的update()方法时,Customer对象被加入到session2的缓存中,因此也成为session2的持久化对象。接下来修改Customer对象的name属性,会导致两个Session实例在清理各自的缓存时,都执行相同的update语句:

update CUSTOMERS set NAME='Jack' …… where ID=1;
在实际应用程序中,应该避免一个Java对象同时被多个Session实例关联,因为这会导致重复执行SQL语句,并且极容易出现一些并发问题。

 游离对象的特征

游离对象具有以下特征:
(1) 不再位于Session的缓存中,也可以说,游离对象不被Session关联。
(2) 游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。

游离对象与临时对象的相同之处在于,两者都不被Session关联,因此Hibernate不会保证它们的属性变化与数据库保持同步。游离对象与临时对象的区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应的记录,而后者在数据库中没有对应的记录。

Session的以下方法使持久化对象转变为游离对象:
(1) 当调用Session的close()方法时,Session的缓存被清空,缓存中的所有持久化对象都变为游离对象。如果在应用程序中没有引用变量引用这些游离对象,它们就会结束生命周期。
(2)Session的evict()方法能够从缓存中删除一个持久化对象,使它变为游离状态。当Session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,可以考虑调用evict()方法,从缓存中删除一些持久化对象。但是多数情况下不推荐使用evict()方法,而应该通过查询语言,或者显式的导航来控制对象图的深度。

分享到:
评论

相关推荐

    域对象在持久化层的状态

    域对象,通常指业务逻辑中的实体类,它们在持久化层中主要存在三种状态:临时状态、持久化状态和游离状态。每种状态都代表了对象与持久化框架(如Hibernate)之间的不同关系,进而影响着对象的生命周期管理和数据库...

    持久层设计

    - **关系型数据库**:这是最常见的一种持久层形式,通过SQL查询来访问和更新数据。 - **NoSQL数据库**:这类数据库通常用于非结构化或半结构化数据的存储,如文档数据库、键值存储等。 - **对象关系映射(ORM)**:...

    Hibernate执行持久层访问步骤

    《Hibernate执行持久层访问步骤详解》 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。它允许开发者使用面向对象的方式进行数据操作,而无需关注底层的SQL语句。本文将...

    持久层和持久化

    在Java开发中,持久层和持久化是两个关键的概念,它们是对象与数据库交互的核心。本文将探讨iBATIS、Hibernate以及Java Persistence API (JPA)这三种流行的持久化框架,并进行对比分析。 首先,持久层(Persistence...

    利用反射实现的持久层工具类(学习)

    在Java编程领域,持久层是应用系统中负责数据存储与检索的部分,它的主要任务是将对象的状态保存到数据库中,并能从数据库中恢复这些状态。本文将深入探讨如何利用反射机制来实现一个简单的持久层工具类,以供学习和...

    面向应用的持久层设计

    3. **高内聚**:持久层内部的功能应该紧密相关,所有的操作都是为了实现数据的持久化。避免在这个层中混入与数据存储无关的逻辑。 4. **通用性和扩展性**:设计时要考虑未来可能的变化,比如数据库类型的变更或是新...

    设计健壮的关系数据库持久层

    文档中介绍了一种基于类的架构来实现持久层: 1. **持久对象类(Persistent Object Class)**:代表了数据库中的记录或行,包含业务逻辑和持久化逻辑。 2. **持久标准类层次(Persistent Criteria Class Hierarchy...

    文件系统持久层 sst256401 stm25p64

    在嵌入式系统中,文件系统的持久层设计至关重要,因为它直接影响到数据的可靠性和效率。针对大容量、大擦除块的SPI接口Flash设备,如SST256401和STM25P64,其特有的硬件特性为文件系统设计带来了一定挑战。 SST...

    Hibernate持久层方法汇总

    本文将详细介绍Hibernate持久层中的一些核心方法,包括`session.load`, `session.find`, `session.iterator`, `session.save`, `session.update`, `session.saveorupdate`。 1. `session.load()`: - `load()`方法...

    php 轻量db层 持久化层 数据库层

    数据库持久化层是指在应用程序中用于与数据库交互的一层抽象,它负责将对象的状态转换为可以存储的数据格式,并在需要时恢复这些状态。这样做的好处在于,开发者可以不用直接编写SQL语句,而是通过面向对象的方式来...

    鲁棒的数据库持久层设计.pdf

    每种类型都有其特定的优势和适用场景,如关系型数据库持久层适用于需要事务处理和复杂查询的场景,而NoSQL数据库持久层则更适合大数据和高并发的环境。 #### CLASS-TYPE体系结构 CLASS-TYPE体系结构是一种用于持久...

    持久层用户开发手册模板.pdf

    持久层是软件系统中负责数据存储和检索的部分,它为业务逻辑层提供了一种抽象,使得程序员可以不必直接处理SQL语句,而是通过对象化的API进行数据操作。这提高了代码的可读性和可维护性,降低了系统对数据库知识的...

    鲁棒的数据库持久层设计

    CLASS-TYPE体系结构是一种用于描述如何组织和管理持久层中对象的方式。这种体系结构的核心思想是将对象按照其生命周期进行分类,并为每种类型的对象定义相应的处理逻辑。在该体系结构中,主要包含以下几类对象: - ...

    Spring持久层(PDF)

    事务管理是Spring持久层的关键特性之一,它提供了两种事务管理方式: 1. **编程式事务管理**:开发者需在代码中显式地管理事务的开启、提交和回滚,适用于需要精细控制事务边界的情况。 2. **声明式事务管理**:...

    用 hibernate 和 spring 开发持久层.doc

    【标题】: 使用Hibernate和Spring开发持久层 【描述】: 本文主要讲解如何利用Hibernate和Spring框架构建企业级应用的持久层,帮助开发者从初学者到专家的进阶。 【标签】: Hibernate 【正文】: 在Java开发中,...

    数据库持久层的UT测试

    数据库持久层的单元测试(UT)是软件开发过程中的重要环节,主要目的是验证代码的独立模块是否按预期工作。在本场景中,我们关注的是MyBatis作为持久层框架的测试,以及DAO(数据访问对象)层的测试。这里使用的环境...

    数据持久层框架 Hibernate

    Hibernate 是一款开源的Java语言实现的数据持久层框架,它为Java开发者提供了一种对象-关系映射(ORM)工具,使得开发者可以使用面向对象的方式来操作数据库,极大地简化了数据库操作的复杂性。在Java后端开发中,...

    java三层结构开发,很好的利用了MVC结构,尤其是对持久层的理解运用很有帮助与参考价值

    3. 持久层(Model/DAO):持久层主要负责数据的存储和检索,它与数据库进行交互。在Java中,持久层通常使用ORM(Object-Relational Mapping)框架,如Hibernate或MyBatis,来简化数据库操作。ORM框架将Java对象与...

    基于Hibernate的数据持久层关键技术的研究

    3. **静态工厂方法**:为了提高持久层的可访问性和易用性,可以通过静态工厂方法来创建DAO实例。这种方式比直接调用构造器更优雅,同时也便于进行依赖注入和单元测试。 #### 五、总结 通过上述分析,可以看出基于...

Global site tag (gtag.js) - Google Analytics