继承关系映射

 

继承关系映射

cascade和inverse (Employee – Department)

1、  Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:

       none,all,save-update ,delete, lock,refresh,evict,replicate,persist,

       merge,delete-orphan(one-to-many) 。一般对many-to-one,many-to-many不设置级联,在<one-to-one>和<one-to-many>中设置级联。

2、  inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。

       one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。

       注: 配置成one-to-one的对象不维护关联关系

 

课上小实例:

继承的映射:

方式一:

       整个的继承体系就用一张表。设计一张表employee,表结构

字段有    id        name       depart_id        type                      skill              sell            

                                                         0代表普通员工          null           null

                                                         1代表技术员                coding      null

                                                         2代表销售员                    null       销售数量

 

(1)新建子类Skiller.java和Sales.java类:继承父类Employee,也有自己的属性

(2)分析表结构

(3)映射文件employee.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping

    package="com.hbsi.domain">

<!-- 方式一 -->

    <class name="Employee" table="employee" discriminator-value="0">

       <id name="id" column="id">

           <generator class="native"/>

       </id>

       <!-- 定义鉴别器     type属性用来定义鉴别器的类型-->

       <discriminator column="type" type="int"/>

      

       <property name="name" column="name"/>

       <many-to-one name="depart" column="depart_id"/>

       <!-- 它的子类的映射 -->

       <subclass name="Skiller"  discriminator-value="0"><!-- 用来描述子类  discriminator-value="0",用来定义鉴别器的值-->

       <property name="skill"/><!-- 特有的属性,不能加上not-null这样的属性,它是允许为空的! -->

       </subclass>

      

       <subclass name="Sales"  discriminator-value="0">

       <property name="sell"/>

       </subclass>

    </class>

</hibernate-mapping>

type--------鉴别器

       <!-- 定义鉴别器     type属性用来定义鉴别器的类型-->

       <discriminator column="type" type="int"/>

 

这种方法的缺点:关系模型不是很合理。

优点:效率高。

 

方式二:

每个子类一张表,不是存放子类的完整信息,而是存放子类所特有的属性的信息。子类共有的属性是放在employee中的。

employee             skiller              sales

id name depart_id    employee_id skill   employee_id sell

映射文件:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping

    package="com.hbsi.domain">

<!-- 方式二 -->

    <class name="Employee" table="employee">

       <id name="id">

       <generator class="native"/>

       </id>

       <property name="name" column="name"/>

       <many-to-one name="depart" column="depart_id"/>

      

       <!-- 一个子类映射 -->

       <joined-subclass name="Skiller" table="skiller">

           <key column="employee_id"/>

           <property name="skill"/>

       </joined-subclass>

      

       <joined-subclass name="Sales" table="sales">

           <key column="employee_id"/>

           <property name="sell"/>

       </joined-subclass>

    </class>

</hibernate-mapping>

 

。这两种方式都不是完美的,

优点:表格设计合理,没有大量没null的字段

缺点:效率不高。

 

方式三:

    方式一和方式二混合使用,一个类继承体系一张表和每个子类一张表。

employee                           sales               

id name depart_id type skill       employee_id sell

映射文件:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping

    package="com.hbsi.domain">

    <!-- 方式三 -->

    <class name="Employee" table="employee" discriminator-value="0">

       <id name="id">

           <generator class="native"/>

       </id>

       <!-- 设置鉴别器 -->

       <discriminator column="type" type="int"></discriminator>

       <property name="name" column="name"/>

       <many-to-one name="depart" column="depart_id"/>

      

       <!-- 子类型 -->

       <subclass name="Skiller" discriminator-value="1">

           <property name="skill"/>

       </subclass>

      

       <subclass name="Sales" discriminator-value="2">

           <join table="sales">

              <key column="employee_id"/>

               <property name="sell"/>

           </join>

       </subclass>

    </class>

</hibernate-mapping>

 

 

方式四:

    每个具体类一张表,保存的是子类的完整信息。

 

 

映射文件:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping

    package="com.hbsi.domain">

    <!-- 方式四 -->

    <class name="Employee" table="employee">

       <id name="id">

           <generator class="hilo"/>

       </id>

       <property name="name" column="name"/>

       <many-to-one name="depart" column="depart_id"/>

      

       <union-subclass name="Skiller" table="skiller">

           <property name="skill"/>

       </union-subclass>

      

       <union-subclass name="Sales" table="sales">

           <property name="sell"/>

       </union-subclass>

    </class>

</hibernate-mapping>

 

最后:编写测试类TestExtends.java

package com.hbsi.test;

import org.hibernate.Hibernate;

import org.hibernate.Session;

import org.hibernate.Transaction;

import com.hbsi.domain.Department;

import com.hbsi.domain.Employee;

import com.hbsi.domain.Sales;

import com.hbsi.domain.Skiller;

import com.hbsi.hibernate.utils.HibernateUtil;

public class TestExtends {

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       add();

       //查询

       System.out.println("-------------查询的结果----------------");

       query(1);

    }

    static void add(){

       Session s=null;

       Transaction tx=null;

       try{

           s=HibernateUtil.getSession();

           tx=s.beginTransaction();

           //增加

           Department depart=new Department();

           depart.setName("department one");

          

           Employee emp1=new Employee();

           emp1.setName("aaa");

           emp1.setDepart(depart);

          

           Skiller emp2=new Skiller();

           emp2.setName("bbb");

           emp2.setDepart(depart);

           emp2.setSkill("coding");

          

           Sales emp3=new Sales();

           emp3.setName("ccc");

           emp3.setDepart(depart);

           emp3.setSell(1000);

           //保存

           s.save(emp1);

           s.save(emp2);

           s.save(emp3);

           s.save(depart);

           //提交事务

           tx.commit();

       }finally{

           if(s!=null)

              s.close();

       }

    }

    static void query(int empId){

       Session s=null;

       Transaction tx=null;

       try{

           s=HibernateUtil.getSession();

           tx=s.beginTransaction();

           //查询

           Employee emp=(Employee) s.get(Employee.class,empId);

           System.out.println("员工的姓名:"+emp.getName()+" ,员工类型 :"+emp.getClass());

           if(emp instanceof Skiller){

              ((Skiller) emp).getSkill();

           }else if(emp instanceof Sales){

              ((Sales) emp).getSell();

           }

           //提交

           tx.commit();

       }finally{

           if(s!=null)

              s.close();

       }

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值