接续上一个主题,我们来看看继承关系映像的第三种方式,我们给予父类别与每个子类别一个表格,与第一个方法不同的是,父类别映像的表格与子类别映像的表格共享相同的主键值,父类别表格只记录本身的属性,如果要查询的是子类别,则透过外键参考从父类别表格中取得继承而来的属性数据。
直接以图片说明会比较容易理解,我们使用前一个主题中的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./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 |
|
来自: WindySky > 《Hibernate入门》