hibernate中对象与对象的关系(三):组件映射

hibernate中,component是某个实体的逻辑组成部分,它与实体的根本区别是没有oid(对象标识符),component是一个被包含的对象,它作为值类型被持久化,而非一个实体。

下面举两个例子说明其使用和配置:

1.以User和Address为例,一个User有id(Long类型)、name(String类型)、address地址(Address类型),其中Address类中没有id属性(即无对象标识符),则address就是User的一个component组件。

User持久化类:

 

public class User {
    private Long id;
    private String name;
    private Address address;
  //省略get,set方法
}

 

组件类Address:

 

public class Address {

    private String country;// 国家
    private String province;// 省份
    private String city;// 城市
    //省略get,set方法
}    

 

User.hbm.xml配置:

 

<hibernate-mapping package="objectn.exus.s6_componentmapping">
    <class name="User">
        <id name="id">
            <generator class="native"/>
        </id>
      <property name="name" />
    ------------------------------------------------------------------------- 
     <component name="address">
             <property name="country" class="Address"></property>
             <property name="province"></property>
             <property name="city"></property>
     </component>
    -------------------------------------------------------------------------
    </class>
</hibernate-mapping>

 

说明:

①:User类映射的表为user,id为主键,name为User的一般属性,被映射为name字段.

②:<component>指定User类的address为User的组件,address并不是一个可以直接映射为字段的属性,而是一个类的对象,class指定类的名称,<component>的子元素<property>指定组件类的属性与user表字段的映射关系.

③:不必为Address写一个Address.hbm.xml映射文件,因为Address是作为User的一部分即值类型而不是实体被持久化的,所以Address的属性会与User的其它属性一样被映射为users表中的字段,而不会将Address映射为单独的一个表。

④:user表的结构为:

保存user对象:

public void testUserSave() {
        Address address=new Address("国家", "省份", "城市");
        User user=new User("张三", address);
        user.setAddress(address);
        Session session = HibernateUtils.getSession();
        Transaction transaction = session.beginTransaction();
        session.save(user);
        transaction.commit();
        session.close();
    }

执行的SQL语句为:

Hibernate: insert into User (name, country, province, city) values (?, ?, ?, ?)

2.若User可有多个地址,即User类中的address属性为Set<Address>类型时,配置如下:

持久化类User:

 

public class User {
    private Long id;
    private String name;
    private Set<Address> address = new HashSet<>();
      //省略get,set方法           
}

 

Address类不变:

配置user.hbm.xml:

<hibernate-mapping package="objectn.exus.s6_componentmapping">
    <class name="User">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="name" />
        <!--注意<set>中并不是<one-to-many>而是<composite-element> -->
        <set name="address" table="address_table">
            <key column="user_id"></key>
            <composite-element class="Address">
                <property name="country"></property>
                <property name="province"></property>
                <property name="city"></property>
            </composite-element>
        </set>
    </class>
</hibernate-mapping>

说明:

①:与一对多关联关系不同,<set>中使用的不是<one-to-many>而是<composite-element>,Hibernate会将User对象address属性(Set类型)中的所有元素映射到另外一张表中(显然user表中的记录不能表示Set中的多个元素),table属性指定另外一张表的名称为"address_table",该表存放Set中的元素,并且该表中还有一个参照user表id的外键字段user_id.

②:user表与address_table表的结构为:(使用Hibernate自动建表功能创建)

address_table表的各字段说明:

可以发现address_table表中并没有主键,只有user_id参照user表中的主键id。

保存User对象:

public void testUserSave() {
        Address address = new Address("中国", "陕西", "123");
        Address address1 = new Address("中国", "河北", "456");
        Address address2 = new Address("中国", "河南", "789");
        User user = new User("张三");
        User user1 = new User("李四");
        user.getAddress().add(address);
        user.getAddress().add(address1);
        user.getAddress().add(address2);

        user1.getAddress().add(address);
        user1.getAddress().add(address1);
        user1.getAddress().add(address2);
        Session session = HibernateUtils.getSession();
        Transaction transaction = session.beginTransaction();
        session.save(user);
        session.save(user1);

        transaction.commit();
        session.close();
    }

输出的SQL语句为:

Hibernate: insert into User (name) values (?)
Hibernate: insert into User (name) values (?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)
Hibernate: insert into address_table (user_id, country, province, city) values (?, ?, ?, ?)

 

posted on 2017-03-19 19:51  超人不会飞丿  阅读(195)  评论(0编辑  收藏  举报

导航