组件映射
组件映射的引出
假设我们有一个Person实体类,该实体类有id,name,地址信息(province,city,street)等;而其他的一些类中也会有地址信息,比如Student实体类、Customer实体类,这时我们可以把地址信息单独抽象出来封装到一个Address类中,在把Address对象作为其他实体类的属性,以实现代码重用。但是,我们把实体类映射到表中时,需不需要单独为Address类创建一个表呢?实际上单独为Address类配置一个表过于繁琐,因为Address信息比较简单,而且还需配置各个类与Address表的关系。其实,我们只要可以在各个实体类中增加简单的几列就可以存储Address信息。例如,当我们映射实体类Person的一个对象到数据库中时,此对象其中的Address属性应该保持到关联地址信息的栏位,而当我们取数据时,地址信息又应该被封装成Address对象保存在实体类中。这就是组件映射,把Address当成Person的一个组件。
组件映射
组件映射是指在一个实体类中有一个属性为自定义类,但自定义类中没有OID(Object Identifier:对象标识符),在数据库中也没有对应的这个类的表。
表结构
客户表(t_customer)
CREATE TABLE t_customer(
id NUMBER(10) PRIMARY KEY,
name VARCHAR2(20),
province VARCHAR2(20),
city VARCHAR2(20),
street VARCHAR2(20),
);
类结构
我们建立Customer和Address这两个类的类结构,并且设置两个类之间的双向关联关系。
Customer类
public class Customer{
private Integer id;
private String name;
private Address address;
...
}
Address 类
public class Address{
private String province;
private String city;
private String steet;
private Customer customer;
...
}
映射文件
使用component这种表签来说明类中有address这种组件,当然我们知道这种name=”address”指的是类中有这个setter和getter方法(property)。
parent标签可以配置两个类的双向关联关系,也就是说,当我们成功查询之后,封装的Address类对象里也通过customer这种属性(property)封装了Customer信息,从而建立起双向关联关系,这正对应我们前面的类结构。
<class name="Customer" table="T_CUSTOMER">
......
<component name="address" class="Address">
<parent name="customer"/>
<property name="province" type="string" column="province"></property>
<property name="city" type="string" column="city"></property>
<property name="street" type="string" column="street"></property>
</component>
</class>
编写component.hbm.xml,并将映射文件配置到核心配置文件中(hibernate.cfg.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!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.li.component.pojo">
<class name="Customer" table="T_CUSTOMER">
<id name="id" type="long" column="ID">
<generator class="assigned"></generator>
</id>
<property name="name" type="string" column="name"></property>
<component name="address" class="Address">
<parent name="customer"/>
<property name="province" type="string" column="province"></property>
<property name="city" type="string" column="city"></property>
<property name="street" type="string" column="street"></property>
</component>
</class>
</hibernate-mapping>
测试
package com.li.component.pojo;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.li.common.HibernateSessionFactory;
/*组件映射的测试类*/
public class CustomerTest {
public static void main(String[] args) {
Customer customer=new Customer();
customer.setId(123L);
customer.setName("Li");
Address address=new Address();
address.setProvince("湖南");
address.setCity("永州");
address.setStreet("开往幸福的路");
customer.setAddress(address);
Session session=HibernateSessionFactory.getSession();
Transaction trans=null;
try {
trans=session.beginTransaction();
/*保存*/
//session.save(customer);
Customer c=(Customer)session.get(Customer.class, 123L);
System.out.println(c.toString());
System.out.println(c.getAddress().getCustomer());
trans.commit();
} catch (Exception e) {
e.printStackTrace();
trans.rollback();
}
}
}