下面使用Annotation来定义一个实体类:
@Entity
@Table(name="person_table") //不是引入org.hibernate.persistence,因为这个只可以在hibernate环境下使用
public class Person //应引用javax.persistence,其实Annotation最后是放在get方法上面,更不容易出问题
{
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name="first"
, column=@Column(name="person_first")),
@AttributeOverride(name="last"
, column=@Column(name="person_last" , length=20))
})
private Name name;
//普通属性
@Column(name="person_email")
private String email;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="name"
, column=@Column(name="cat_name" , length=35)),
@AttributeOverride(name="color"
, column=@Column(name="cat_color"))
})
//组件属性,代表此人拥有的宠物
private Cat pet;
//省略name属性的setter和getter方法
...
//省略email属性的setter和getter方法
...
//省略pet属性的setter和getter方法
...
}
上面程序的粗体字代码就可管理实体类与数据表之间的映射关系,其中@Entity用于标注该类是一个持久化类,@ EmbeddedId用于标注复合类型的标识属性,而@Embedded用于标注一个组件属性,也就是说Person的name属性就是一个复合类型的标识属性;pet属性是一个组件属性。
上面程序还用了Name类,它是一个Person实体的标识属性的类型,程序使用@Embeddable标注它即可。如下代码所示:
//修饰组件属性类
@Embeddable
public class Name
implements java.io.Serializable
{
private String first;
private String last;
//无参数的构造器
public Name()
{
}
//初始化全部属性的构造器
public Name(String first , String last)
{
this.first = first;
this.last = last;
}
//省略first属性的setter和getter方法
...
//省略last属性的setter和getter方法
...
//提供重写的equals方法
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj.getClass() == Name.class)
{
Name target = (Name)obj;
if (target.getFirst().equals(first)
&& target.getLast().equals(last))
{
return true;
}
}
return false;
}
//提供重写的hashCode方法
public int hashCode()
{
return first.hashCode() + last.hashCode() * 17;
}
}
上面Name类需要作为标识属性的类型,因此一样需要实现java.io.Serializable接口,并重写了hashCode()和equals()两个方法。
至于Person类所包含的组件属性pet,它所属的Cat类也只要简单地使用@Embeddable修饰即可,下面是该Cat类的代码:
//修饰组件属性类
@Embeddable
public class Cat
{
private String name;
private String color;
//无参数的构造器
public Cat()
{
}
//初始化全部属性的构造器
public Cat(String name , String color)
{
this.name = name;
this.color = color;
}
//省略name属性的setter和getter方法
...
//省略color属性的setter和getter方法
...
}
一旦在实体类中通过上面Annotation进行标注之后,Hibernate已经能够理解实体类与数据表之间的映射关系了,也就不再需要*.hbm.xml的映射文件了。此时要将hibernate.cfg.xml文件略做修改——告诉它去加载指定实体类,而不是根据映射文件加载。本应用所使用的hibernate.cfg.xml文件代码如下:
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate- configuration是连接配置文件的根元素 -->
<hibernate-configuration>
<session-factory>
<!-- 省略其他配置属性 -->
...
<!-- 罗列所有的持久化类 -->
<mapping class="org.crazyit.app.domain.Person"/>
</session-factory>
</hibernate-configuration>
经过上面修改之后,主程序不需要任何改变。不管使用XML映射文件管理实体的映射、还是采用Annotation管理实体的映射,Hibernate的处理完全相同。