入門 09 - 繼承映射2

接續上一個主題,我們來看看繼承關係映射的第三種方式,我們給予父類別與每個子類別一個表格,與第一個方法不同的是,父類別映射的表格與子類別映射的表格共享相同的主鍵值,父類別表格只記錄本身的屬性,如果要查詢的是子類別,則透過外鍵參考從父類別表格中取得繼承而來的屬性資料。

 直接以圖片說明會比較容易理解,我們使用前一個主題中的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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值