组件映射
Hibernate建议在进行领域模型建模时要细粒度一些,简单的说,类要比表多,这种映射方式就是组建映射。
组件类是值类型的,即它没有对象标识符属性,在数据库中也没有对应的表,它只隶属于另一个持久化类的实例。它的数据被嵌入到所隶属的持久化实例对应的数据库表的数据中。
组建映射的应用有三种常见情况:把组件类做为持久化类的单个属性来使用、把组件类作为持久化类的集合属性来使用、把组件类作为持久化类的对象标识符来使用。
关联的属性是个复杂类型的持久化类,但不是实体即:数据库中没有表与该属性对应,但该类的属性要持久保存的。
1、组件类作为持久化类的单个属性
定义一个Address类
public class Address {
private String province;
private String city;
private String detail;
private String zipcode;
private String telephone;
private String mobilephone;}
public class Customer {
private String id;
private String loginname;
private String password;
private String email;
private Address homeAddress;
private Address deliverAddress;
它对应的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="com.hbsi.domain">
<class name="Customer" table="customer"><!--unsaved-value="-1"来指定 -->
<id name="id"column="id">
<generator class="native"/><!-- native主键的生成器 自动增长 -->
</id>
<property name="loginname"not-null="true"/><!-- 映射普通的java属性 -->
<property name="password"not-null="true"/>
<property name="email"/>
<!-- 用component元素映射组件类属性homeAddress -->
<component name="homeAddress"class="Address">
<!-- 用property映射组件类的每个属性 -->
<property name="province"column="home_province"/>
<property name="city"column="home_city"/>
<property name="detail"column="home_detail"/>
<property name="zipcode"column="home_zipcode"/>
<property name="telephone"column="home_telephone"/>
<property name="mobilephone"column="home_mobilephone"/>
</component>
<!-- 用component元素映射组件类属性deliverAddress -->
<component name="deliverAddress"class="Address">
<property name="province"column="deliver_province"/>
<property name="city"column="deliver_city"/>
<property name="detail"column="deliver_detail"/>
<property name="zipcode"column="deliver_zipcode"/>
<property name="telephone"column="deliver_telephone"/>
<property name="mobilephone"column="deliver_mobilephone"/>
</component>
</class>
</hibernate-mapping>
2、组件类作为持久化类的集合属性
照片类
public class Photo {
private String name;
private String filePath;
private String despriction;
private String width;
private String height;
}
相册持久化类
public class Album {
private Long id;
private String title;
private String description;
private String creationTime;
private List<Photo> photos;
}
对应的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="com.hbsi.domain">
<class name="Album" table="album"><!--unsaved-value="-1"来指定 -->
<id name="id"column="id">
<generator class="native"/><!-- native主键的生成器 自动增长 -->
</id>
<property name="title"not-null="true"/><!-- 映射普通的java属性 -->
<property name="description"not-null="true"/>
<property name="creationTime"column=”creation_time”/>
<!-- 用bag来映射List集合属性 -->
<bag name="photos"class="photo">
<keycolumn=”album_id” not-null=”true”/>
<composite-elementclass=”Photo”>
<property name="name"/>
<property name="filePath"column="file_path"/>
<property name="description"/>
<property name="width"/>
<property name="height"/>
</composite-element>
</bag>
</class>
</hibernate-mapping>
3、组件类作为持久化类的对象标识符属性
Hibernate要求,作为复合对象标识符类的Useroid类必须实现java.io.Serializable,且要作为复合标识符的属性重写hashCode()方法和equals()方法。
复合标识符的映射采用composite-id元素来完成。需要注意的是,如果是一个全新的项目开发,不建议使用复合对象标识符,即不建议使用复合主键,因为这样会使应用变得复杂,不具有可扩展子性和可维护性。