技术开发 频道

Hibernate应用系列之四映射篇


【IT168 专稿】

    Hibernate是近年非常流行的对象持久化框架(Framework)。这一点从Hibernate的名子就可以看得出,Hibernate的中文意思是“冬眠”,这就意味着一动不动,当然也就是持久的意思了。

    Hibernate在映射时有一个映射三角形。映射三角形的三个顶点是Hibernate所能互相转换的三种映射实体。它们分别是:
 Java持久化类。
 映射文件。
 数据库表。
   
    拥有以上三种实体中的任意两个,就可以得到另外一个。在Hibernate2.0及以前的版本中,只能通过Java类和映射文件配合才能将一个数据库表持久化。然而这样做将会带来很多不利的影响。如设置xml格式的映射文件是非常繁琐的;由于映射关系是单独保存在映射文件中的,这样不利于直观地描述Java持久化类和数据库表的映射关系。
   
    以上所述的种种弊端随着Hibernate3.0的发布而得到很好的解决。由于Hibernate3.0使用了J2SE5.0的注释(Annotations)技术,因此,Hibernate3.0不仅可以使用映射文件描述和数据库表的映射关系,而且可以将这种映射关系直接在Java源程序中描述,使Java持久化类成为描述的Java类。说到这,大家一定会问,什么是注释(Annotations)技术呢?下面就让我们一起来了解一下什么是J2SE5.0的注释技术。

    一、 注释技术
    如果用一句话解释什么是注释技术,那么这句话就是:注释就是用于描述Java类中成员(如属性、方法)的含义一种语法形式。大家可能对这句话还没太理解,那么让我来举个例子说明一下。
@Entity public class MyClass { @MethodAnnotation public void method1(){} @MethodAnnotation(attr=”attrvalue”) public void method2(){} }
    上面是一个普通的Java类。其中蓝色的三行就是注释的语句。其中@Entity表示的是整个MyClass的含义。而@MethodAnnotation和@MethodAnnotation(attr=”attrvalue”)分别表示的是method1和method2的含义。那么@后跟的是什么呢?
   
    实际上注释也是需要定义的,@后跟的就是已经定义的注释。它的定义有些类似于接口(Interface)。一个最简单的注释定义代码如下:
public @Interface MyAnnotation
{
}
    以上代码如果删除蓝色的@后,就是接口的定义。我们可以在任何Java程序中使用它。
public class TestAnnotation
{
@ MyAnnotation
public void method(){}
}

    当然,MyAnnotation只是个空的注释,它什么作用也不起。如果要加入相应的属性,可以象在接口中加入方法一下加入相应的属性。
public @Interface MyAnnotation { String name(); int age(); } 可以按如下语法使用上面的注释。 public class TestAnnotation { @ MyAnnotation(name=”sun”, age=20) public void method(){} } 还可以给注释的属性加上默认值。 public @Interface MyAnnotation { String name() default “sun” ; int age() default 20 ; }

有了默认值,在使用它时如果需要设置的值正好就是默认值,可以不用再为注释的属性赋值。
public class TestAnnotation { @ MyAnnotation public void method(){} }
    method方法通过MyAnnotation的描述,已经具备了两个属性:name和age,它们的值分别为”sun”和20。即然能够为其设置属性,当然,也可以将这些属性读出来,以便根据这些属性对方法进行处理。由于本文的主题不是讨论注释技术的,因此,对此不再做深入的探讨,感兴趣的读者可以访问http://Java.sun.com/j2se/1.5.0/docs/guide/language/了解更详细的信息。 

   
【IT168 专稿】

    
    二、使用注释技术建立Hibernate映射

   
    上面简单地介绍了J2SE5.0提供的注释技术,在这一部分让我们来讨论如何使用注释技术来为Hibernate建立映射。
在传统的建立Hibernate映射的方法中,可以在您的POJO(plan old Java objects)源代码中加入Hibernate所定义的Java doclet标签。然后使用开源的XDoclet生成XML格式的映射文件。当然,我们可以使用ant工具简化这一过程。但是使用这种方式必须掌握大量的工具,而且使用起来比较繁琐。但使用注释技术,我们就可以将这些烦人的工具扔到垃圾箱里了。

    由于注释的作用是描述类以及其成员的属性含义。因此,Hibernate3预定义了很多用于描述Java持久化类的注释。在使用注释前,您需要安装Hibernate3注释工具包。这个工具包可以从http://www.hibernate.org下载。当然,还需要支持注释技术的J2SE5.0。在发布使用注释技术的应用程序时,需要两个*.jar包:hibernate-annotations.jar和ejb-3.0-edr2.jar。由于ejb3的规范还未完成,可能sun的ejb3的*.jar包已经变化。因此,建议使用工具包中带的ejb3的*.jar,这样,就可以保持和hibernate-annotations.jar的一至性。

    由于预定义的注释很多,因此,本文只介绍主要的几个。
    @Entity 
    这是定义一个持久化类要使用的第一个注释。这个注释要写在类的前面。如果使用了它,就表示已经将这个类声明为Entity
Bean(EJB3中的实体Bean,Hibernate借用了很多EJB3中预定义的注释)。 import Javax.persistence.*; @Entity public class MyClass { }
    当然,还可以对Entity设置一些属性。如果要让MyClass类使用getter方法,需要将@Entity改为@Entity (access=AccessType.PROPERTY)。红色部分为访问权限。如果想要直接使用字段,可以使用@Entity (access=AccessType.FIELD)。

    @Id
    设计数据库表时,一般为每一个表设置一个主键。这个主键也必须在持久化对象上有所体现。因此,Hibernate3加入了Id注释。这个注释使用起来很简单。可对Id设置5种主键类型。

    1. NONE
    没有主键。如果设置这个值,应用程序将为其自动产生一个主键。
    2. AUTO
    这个主键是自动产生的。这个属性值依赖数据库本身的字段值自增机制。
    3. IDENTITY
    唯一索引。
    4. SEQUENCE
    有一些数据库支持建立SEQUENCE类型的字段。如果使用这种数据库,可以使用这个属性值。
    5. TABLE
    使用这个主键类型可以根据主键值将表分开。

    一个使用@Id的例子
@Id (generate=GeneratorType.AUTO) public int getMyId() { return myID; }
    @Basic 和 @Transient
    这两个属性是用来定义持久化类型的属性。如果为某一个字段字义了@Basic,那么当这个字段保存时,它的值将被回写到数据库中。如果使用@Transient,则这个字段就变成了临时的,它的变化并不被保存到数据库中。
@Basic public void getMethod1(){} @Transient public void getMethod2(){} @Column
    这个注释使用的频率非常高。它是用来定义持久化类中的字段和数据库表中的某一个字段的对应关系。

@Column(name="field1",length=10, nullable=false) public String getField1() { return field1; }
    在上面的代码中定义了getField1所对应的数据库表的字段为field1,字段长度为10,并且这个字段不能为null。

    一个实际的例子
    下面以一个完整的例子说明如何使用注释来建立Hibernate映射。先给出一个用xml格式的映射文件。
<?xml version="1.0"?> <hibernate-mapping package="com.examples"> <class name="Table1" table="table1"> <id name="id" column="uid" type="long"> <generator class="native"/> </id> <property name="name" type="string"/> <property name="birthDate" column="birthdate" type="date"/> <property name="age" type="integer"/> </class> </hibernate-mapping>
    下面给出一个利用注释来建立的和上面映射文件具有同样效果的Java源程序文件。
@Entity @Table(name="table1") public class Table1 { @Id(generate=GeneratorType.AUTO) @Column(name="uid") private Long id; @Basic @Column(length="100", unique="true") private String name; @Basic @Column(name="birthdate") private Date birthDate; public void setId(Long id) { this.id = id; } public Long getId() { return this.id; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } public Date getBirthDate() { return this.birthDate; } }
    以上代码中蓝色部分是注释语句。看一看,是不是比xml格式的映射文件简单多了,而且映射关系和源程序放到一起,更有助于程序的维护,也有助于程序的可读性。

    总结
    本文所讨论的使用J2SE5.0的注释技术为Hibernate建立映射是Hibernate3新提供的建立映射的方法。这种方法紧密依赖于J2SE5.0。而且Hibernate3的Hibernate工具包还处于beta阶段。如果您为了和以前的hibernate和J2SE版本兼容以及使程序更为稳定,建议你仍然使用传统的方法建立hibernate映射。当然,如果为了体验hibernate3和J2SE5.0的新特性以及为了获得更高的开发效率,使用新的方法生成hibernate映射也许是更好的选择。
0
相关文章