您的位置:首页 > 其它

Hibernate之持久化对象

2016-03-06 18:03 190 查看
Hibernate是一个纯粹的O/RMapping框架,通过Hibernate的支持,程序开发者只需要管理对象的状态,无须理会底层数据库系统的细节。相当于常见的JDBC持久层方案中需要手工管理SQL语句,Hibernate采用完全面向对象的方式来操作数据库。对于程序开发者而言,眼里只有对象、属性,无须理会底层数据表、数据列等概念。

1. 持久化类的要求

虽然Hibernate对持久类滑太远的要求,但还是应该遵守如下规则:

1) 提供一个无参数的构造器:所有的持久化类都应该提供一个无参数的构造器,这个构造器可以不采用public访问控制符。只要提供了无参数的构造器,Hibernate就可以使用Constructor.newInstance()来创建持久类的实例了。通常,为了方便Hibernate在运行时生成代理,构造器的的访问控制参数符至少是包含可见的,即大于或等于默认的访问控制符。

2) 提供一个标识属性:标识属性通常映射数据库的主键字段。这个属性可以叫任何名字,其类型可以是任何的基本类型、基本类型的包装、java.lang.Sring或者java.util.Date。如果使用了数据库表的联合主键,甚至可以用一个用户自定义的类,该类拥有这些类型的属性。当然,也可以不指定任何标识属性,而是在持久化注解中直接将多个普通映射成一个联合主键,但通常不推荐这么做。

Hibernate建议使用可以为空的类型来作为标识属性的类型,因为应该尽量避免使用基本数据类型。

1) 为持久化类的每个成员变量提供setter和getter方法:Hibernate默认采用属性方式来访问持久化成员变量。

2) 使用非final的类:在运行时生成代理是Hibernate的一个重要功能。如果持久类没有实现任何接口,Hibernate使用Javassist生成代理,该代理对象是持久化类的子类的实例。如果使用了final类,则无法生成Javassist代理,将无法进行性能优化。如果非要使用一个有public final方法的类,则必须通过设置lazy=”false”来明确地禁用代理。

3) 重写equels()和hashCode()方法:如果需要把持久化类的实例放入Set中,则应该为持久化类重写equals()和hashCode()方法。实现equals()/hashCode()最显而易见的方法是比较两个对象标识属性的值。

2. 持久化对象的状态

上一章节中,笔者已经介绍过了持久化,那么这里,我们深入来了解一个持久化。Hibernate持久化对象支持如下几种的状态。

1) 瞬态:对象由new操作符创建,且尚未与Hibernate Session关联的对象被认为处于瞬态。瞬态对象不会被持久化到数据库,也不会被赋予持久化标识。如果程序中失去了瞬态对象的引用,瞬态对象将被垃圾回收机制销毁。使用Hibernate Session可能将其变为持久化状态。

2) 持久化:持久化实例在数据库中有对应的记录,并拥有一个持久化标识(idebtifier).持久化的实例可能是刚刚保存的,也可以是刚刚被加载的。无论哪一种,持久化对象必须与指定的Hibernate Session关联。Hibernate会检测到处于持久化状态对象的改动,在当前操作执行完成时将对象数据写回数据库。开发者不需要手动执行update。

3) 脱管:某个实例曾经处于持久化状态,但随着与之关联Session被关闭,该对象就变成脱管状态。脱管对象的引用依然有效,对象可继续被修改。如果重新让脱管对象与Session关联,这个脱管对象会重新转换为持久状态,而脱管期间的改动不会丢失,也可以被写入数据库。正是因为这个功能,逻辑上长事务成为可能,它被称为应用程序事务,即事务可以跨越用户的思考,因为当对象处于脱管状态时,对该对象的操作无须锁定数据库,不会造成性能的下降。

下面显示Hibernate持久化对象演化图。



3. 总结

理解Hibernate的持久化的三个状态,我助于自己对于JavaBean对象的状态的认识,及自己对数据的操作。在操作中也可更好地优化程序。当然,对于持久化对象状态的方法,我们将在下一节中讲解。在这之前,希望读者可以更好地理解持久化的三种状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: