Hibernate入门09 - 继承映射2

来源:互联网 发布:mac怎么打开身份不明 编辑:程序博客网 时间:2024/05/17 01:39
 接续上一个主题,我们来看看继承关系映像的第三种方式,我们给予父类别与每个子类别一个表格,与第一个方法不同的是,父类别映像的表格与子类别映像的表 格共享相同的主键值,父类别表格只记录本身的属性,如果要查询的是子类别,则透过外键参考从父类别表格中取得继承而来的属性数据。
 直接以图片说明会比较容易理解,我们使用前一个主题中的User、PowerUser与GuestUser类别作说明,类别继承图如下:

 其映像至数据库表格的关系如下:

 其中POWER_USER与GUEST_USER表格的主键值将与USER表格的主键值相同,POWER_USER_ID与GUEST_USER_ID作为一个外键参考,以取得父类别映像表格的NAME与PASSWORD数据。
 在映射文件中要实现这种映像,我们使用<joined-subclass>卷标,并使用<key>卷标指定子类别表格与父类别表格共享的主键值,映像文件的撰写方式如下:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
 
<hibernate-mapping>
 
    <class name="onlyfun.caterpillar.User" table="USER">
 
        <id name="id" type="string" unsaved-value="null">
            <column name="USER_ID"/>
            <generator class="uuid.hex"/>
        </id>
 
        <property name="name" type="string" not-null="true">
            <column name="NAME" length="16" not-null="true"/>
        </property>
 
        <property name="password" type="string" not-null="true">
            <column name="PASSWORD" length="16" not-null="true"/>
        </property>
 
        <joined-subclass name="onlyfun.caterpillar.PowerUser" table="POWER_USER">
            <key column="POWER_USER_ID"/>
            <property name="level" type="int" column="POWER_USER_LEVEL"/>
            <property name="otherOfPower" type="string" column="POWER_OTHER"/>
        </joined-subclass>
      
        <joined-subclass name="onlyfun.caterpillar.GuestUser" table="GUEST_USER">
            <key column="GUEST_USER_ID"/>
            <property name="otherOfGuest" type="string" column="GUEST_OTHER"/>
        </joined-subclass>
    </class>
 
</hibernate-mapping>

 您可以自行建立数据库与表格,当然使用SchemaExportTask帮您自动建立表格是更方便的,下面是SchemaExportTask自动建立表格时所使用的SQL:
[schemaexport] alter table GUEST_USER drop constraint FKB62739F25ED19688;
[schemaexport] alter table POWER_USER drop constraint FK38F5D2E586CA74B5;
[schemaexport] drop table if exists USER;
[schemaexport] drop table if exists GUEST_USER;
[schemaexport] drop table if exists POWER_USER;
[schemaexport] create table USER (
[schemaexport] USER_ID varchar(255) not null,
[schemaexport] NAME varchar(16) not null,
[schemaexport] PASSWORD varchar(16) not null,
[schemaexport] primary key (USER_ID)
[schemaexport] );
[schemaexport] create table GUEST_USER (
[schemaexport] GUEST_USER_ID varchar(255) not null,
[schemaexport] GUEST_OTHER varchar(255),
[schemaexport] primary key (GUEST_USER_ID)
[schemaexport] );
[schemaexport] create table POWER_USER (
[schemaexport] POWER_USER_ID varchar(255) not null,
[schemaexport] POWER_USER_LEVEL integer,
[schemaexport] POWER_OTHER varchar(255),
[schemaexport] primary key (POWER_USER_ID)
[schemaexport] );
[schemaexport] alter table GUEST_USER add index FKB62739F25ED19688 (GUEST_USER_ID),
add constraint FKB62739F25ED19688 foreign key (GUEST_USER_ID) references USER (USER_ID);
[schemaexport] alter table POWER_USER add index FK38F5D2E586CA74B5 (POWER_USER_ID),
add constraint FK38F5D2E586CA74B5 foreign key (POWER_USER_ID) references USER (USER_ID);

 至于在Java程序的撰写方面,您可以直接使用前一个主题中所写的测试程序(您可以看到,Hibernate将程序撰写与数据库处理的细节分开了),假设我们使用上一个主题的测试程序新增了两笔数据,则数据库表格的结果如下:
mysql> select * from user;
+----------------------------------+-------------+----------+
| USER_ID                          | NAME        | PASSWORD |
+----------------------------------+-------------+----------+
| 297e3dbdff0af72900ff0af72d4b0001 | caterpillar | 123456   |
| 297e3dbdff0af72900ff0af72d4b0002 | momor       | 654321   |
+----------------------------------+-------------+----------+
2 rows in set (0.05 sec)
 
mysql> select * from power_user;
+----------------------------------+------------------+-------------------+
| POWER_USER_ID                    | POWER_USER_LEVEL | POWER_OTHER       |
+----------------------------------+------------------+-------------------+
| 297e3dbdff0af72900ff0af72d4b0001 |                1 | PowerUser's field |
+----------------------------------+------------------+-------------------+
1 row in set (0.00 sec)
 
mysql> select * from guest_user;
+----------------------------------+-------------------+
| GUEST_USER_ID                    | GUEST_OTHER       |
+----------------------------------+-------------------+
| 297e3dbdff0af72900ff0af72d4b0002 | GuestUser's field |
+----------------------------------+-------------------+
1 row in set (0.00 sec)

 了解一下储存数据至数据库时所使用的SQL语句有助于您了解底层的运作方式,新增两笔数据的SQL如下:
Hibernate: insert into USER (NAME, PASSWORD, USER_ID) values (?, ?, ?)
Hibernate: insert into POWER_USER (POWER_USER_LEVEL, POWER_OTHER, POWER_USER_ID) values (?, ?, ?)
Hibernate: insert into USER (NAME, PASSWORD, USER_ID) values (?, ?, ?)
Hibernate: insert into GUEST_USER (GUEST_OTHER, GUEST_USER_ID) values (?, ?)

 有兴趣的话,也可以看一下查询数据时的SQL语句,我们可以看到实际上使用inner join来查询数据,以下是查询PowerUser所使用的SQL:
select poweruser0_.POWER_USER_ID as USER_ID,
       poweruser0_.POWER_USER_LEVEL as POWER_US2_1_,
       poweruser0_.POWER_OTHER as POWER_OT3_1_,
       poweruser0__1_.NAME as NAME0_,
       poweruser0__1_.PASSWORD as PASSWORD0_
       from POWER_USER poweruser0_
       inner join USER poweruser0__1_ on poweruser0_.POWER_USER_ID=poweruser0__1_.USER_ID
原创粉丝点击