zoukankan      html  css  js  c++  java
  • Hibernate继承映射多态关联

    把类之间的继承关系反应到数据库中,三种方法

    (1).只用一个表,子类的属性对应数据库表中额外的字段。使用<discriminator>和<subclass>

    以下例子中Delivery(投递)类的两个子类PostDelivery(邮递)和ExpressDelivery(快递),注意必须在父类中也加上discrminator-value否则报“Could not format discriminator value to SQL string...”错。注意<discriminator>在除id以外的其他子元素之前,否则解析xml文件出错。

     1 <class name="com.tazi.domin.Delivery" table="DELIVERY" discriminator-value="2">
    2 <id name="id" type="java.lang.Integer">
    3 <column name="ID"/>
    4 <generator class="identity"/>
    5 </id>
    6 <discriminator column="delivery_type" type="int"></discriminator>
    7 <property name="phone" type="string" column="phone"/>
    8 <property name="address" type="string" column="address"/>
    9 <property name="postcode" type="string" column="POSTCODE"/>
    10 <subclass name="com.tazi.domin.PostDelivery" discriminator-value="0">
    11 <property name="parcelNumber" column="PARCEL_NUMBER"></property>
    12 </subclass>
    13 <subclass name="com.tazi.domin.ExpressDelivery" discriminator-value="1">
    14 <property name="expressCompany" column="EXPRESS_COMPANY"></property>
    15 <property name="expressNumber" column="EXPRESS_NUMBER"></property>
    16 </subclass>
    17 </class>

    适用于在继承映射中总是需要多态查询,而且子类的属性相对比较少

    (2).每一个具体类一个表

    设置类Delivery为abstract在父类的class标签中也加上abstract="true",主键策略不能再使用identity,可以用increment或hilo.

     1     <class name="com.tazi.domin.Delivery" abstract="true">
    2 <id name="id" type="java.lang.Integer">
    3 <column name="ID"/>
    4 <generator class="increment"/>
    5 </id>
    6 <property name="phone" type="string" column="phone"/>
    7 <property name="address" type="string" column="address"/>
    8 <property name="postcode" type="string" column="POSTCODE"/>
    9 <union-subclass name="com.tazi.domin.PostDelivery" table="POST_DELIVERY">
    10 <property name="parcelNumber" column="PARCEL_NUMBER"></property>
    11 </union-subclass>
    12 <union-subclass name="com.tazi.domin.ExpressDelivery" table="EXPRESS_DELIVERY">
    13 <property name="expressCompany" column="EXPRESS_COMPANY"></property>
    14 <property name="expressNumber" column="EXPRESS_NUMBER"></property>
    15 </union-subclass>
    16 </class>

    例子1:单个子类的操作

    1         PostDelivery pDelivery=new PostDelivery();
    2 pDelivery.setPhone("13526356485");
    3 pDelivery.setAddress("北京西街15号");
    4 pDelivery.setPostcode("100080");
    5 pDelivery.setParcelNumber("8578");
    6 session.save(pDelivery);

    hql输出,它使用union将两个表连起来

     1 Hibernate: 
    2 select
    3 max(ids_.ID)
    4 from
    5 ( select
    6 ID
    7 from
    8 EXPRESS_DELIVERY
    9 union
    10 select
    11 ID
    12 from
    13 POST_DELIVERY
    14 ) ids_
    15 Hibernate:
    16 insert
    17 into
    18 POST_DELIVERY
    19 (phone, address, POSTCODE, PARCEL_NUMBER, ID)
    20 values
    21 (?, ?, ?, ?, ?)

    例子2:多态查询

    1 Query query=session.createQuery("from Delivery");//查询父类得到所有子类的信息
    2 List<Delivery> delivery=query.list();

    3 for(Delivery d:delivery)
    4 System.out.println(d.getAddress());

    输出:

     1 Hibernate: 
    2 select
    3 delivery0_.ID as ID8_,
    4 delivery0_.phone as phone8_,
    5 delivery0_.address as address8_,
    6 delivery0_.POSTCODE as POSTCODE8_,
    7 delivery0_.PARCEL_NUMBER as PARCEL1_9_,
    8 delivery0_.EXPRESS_COMPANY as EXPRESS1_10_,
    9 delivery0_.EXPRESS_NUMBER as EXPRESS2_10_,
    10 delivery0_.clazz_ as clazz_
    11 from
    12 ( select
    13 ID,
    14 phone,
    15 address,
    16 null as EXPRESS_NUMBER,
    17 POSTCODE,
    18 PARCEL_NUMBER,
    19 null as EXPRESS_COMPANY,
    20 1 as clazz_
    21 from
    22 POST_DELIVERY
    23 union
    24 select
    25 ID,
    26 phone,
    27 address,
    28 EXPRESS_NUMBER,
    29 POSTCODE,
    30 null as PARCEL_NUMBER,
    31 EXPRESS_COMPANY,
    32 2 as clazz_
    33 from
    34 EXPRESS_DELIVERY
    35 ) delivery0_
    36 北京西街15号
    37 苏州通信大楼2F

    可见Hibernate把两个子类对应的表的字段合并起来,执行效率低。建议用于父类将来不会修改且不需要多态查询的情况。

    (3)父类子类各有一表,用外键关联,子类表的主键为外键引用父类表的主键

     1 /*mysql*/
    2 create table delivery
    3 (
    4 id int primary key auto_increment,
    5 phone varchar(20),
    6 address varchar(200) not null,
    7 postcode varchar(20)
    8 );
    9 create table post_delivery
    10 (
    11 id int primary key,
    12 parcel_number varchar(20),
    13 foreign key(id) references delivery(id)
    14 );
    15
    16 create table express_delivery
    17 (
    18 id int primary key,
    19 express_company varchar(20),
    20 express_number varchar(20),
    21 foreign key(id) references delivery(id)
    22 );

    例子1:单独子类操作

    1         PostDelivery pDelivery=new PostDelivery();
    2 pDelivery.setPhone("13526356485");
    3 pDelivery.setAddress("北京西街15号");
    4 pDelivery.setPostcode("100080");
    5 pDelivery.setParcelNumber("8578");
    6 session.save(pDelivery);

    输出:

     1 Hibernate: 
    2 insert
    3 into
    4 DELIVERY
    5 (phone, address, POSTCODE)
    6 values
    7 (?, ?, ?)
    8 Hibernate:
    9 insert
    10 into
    11 POST_DELIVERY
    12 (PARCEL_NUMBER, id)
    13 values
    14 (?, ?)

    例子2:多态查询

     1 Hibernate: 
    2 select
    3 delivery0_.ID as ID8_,
    4 delivery0_.phone as phone8_,
    5 delivery0_.address as address8_,
    6 delivery0_.POSTCODE as POSTCODE8_,
    7 delivery0_1_.PARCEL_NUMBER as PARCEL2_9_,
    8 delivery0_2_.EXPRESS_COMPANY as EXPRESS2_10_,
    9 delivery0_2_.EXPRESS_NUMBER as EXPRESS3_10_,
    10 case
    11 when delivery0_1_.id is not null then 1
    12 when delivery0_2_.id is not null then 2
    13 when delivery0_.ID is not null then 0
    14 end as clazz_
    15 from
    16 DELIVERY delivery0_
    17 left outer join
    18 POST_DELIVERY delivery0_1_
    19 on delivery0_.ID=delivery0_1_.id
    20 left outer join
    21 EXPRESS_DELIVERY delivery0_2_
    22 on delivery0_.ID=delivery0_2_.id
    23 北京西街15号
    24 苏州通信大楼2F

    符合数据模型的常规设计规则,类与表的映射匹配更合理。缺点是复杂的类继承下新增数据需要同时操作多个表,查询时通过多个表连接。适用于需要多态查询,同时子类相对来说有较多的新增属性。










  • 相关阅读:
    HOJ 2139 Spiderman's workout(动态规划)
    FZU 2107 Hua Rong Dao(dfs)
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
  • 原文地址:https://www.cnblogs.com/tazi/p/2301695.html
Copyright © 2011-2022 走看看