11.映射继承关系

1.采用 subclass 元素的继承映射

*   每个具体类一张表(table per concrete class) 将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态。

*   父类和子类使用同一张表(有一个区分类型的字段)

*   采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表

*   因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为辨别者列(discriminator).

/**
 * 钟点工
 */
public class HourEmployee  extends Employee{
/**
 * 正式员工
 */
public class SalaryEmployee extends Employee {
hibernate配置文件

<hibernate-mapping>
  <class name="cn.itcast.extends01.Employee" table="employee" discriminator-value="ee">
      <id name="id" type="integer">
        <column name="id"/>
        <generator class="increment"/>
      </id>
      <!--辨别者列,column="etype"用于区分员工的种类,该配置必须放置在id的后面-->
      <discriminator column="etype" type="string"/>
      <property name="name" type="string">
          <column name="name"/>
      </property>
      <!--配置子类
           discriminator-value: 子类对应的辨别者列的值  
      -->
      <subclass name="cn.itcast.extends01.HourEmployee" discriminator-value="he">
        <property name="rate" column="rate" type="double"/>
       </subclass>

      <subclass name="cn.itcast.extends01.SalaryEmployee" discriminator-value="se">
        <property name="salary" column="salary" type="double"/>
      </subclass>
  </class>
  </hibernate-mapping>
*   辨别者列,用于区分员工的种类,该配置必须放置在id的后面

*   普通员工的辨别者列值为ee,小时工辨别者列的值为he,正式员工的辨别者列的值为se
*   在这种映射策略下,使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定辨别者列的值

*   所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保     存到数据库中

SalaryEmployee se=new SalaryEmployee();
se.setName("赵敏");
se.setSalary(3000d);
*   double类型的值要加个d,默认数字都是int类型

1.1查询钟点工信息

@Test
	public  void findHourEmployee(){
		   Session session=sf.openSession();
		   Transaction tx=session.beginTransaction();
		   //可以使用子类
		   Query query=session.createQuery("from HourEmployee");
		   query.list();
		   tx.commit();
		   session.close();
	}
查询语句  Hibernate: select houremploy0_.id as id0_, houremploy0_.name as name0_, houremploy0_.rate as rate0_ from employee houremploy0_ where houremploy0_.etype='he'

*   如果查询所有员工,hql语句为 from Employee  多态查询
2.采用 joined-subclass 元素的继承映射

*   采用 joined-subclass 元素的继承映射可以实现每个子类一张表

*   采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。     于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中

 <hibernate-mapping>
 <class name="cn.itcast.extends02.Employee" table="e_emp" >
      <id name="id" type="integer">
        <column name="id"/>
        <generator class="increment"/>
      </id>
      <property name="name" type="string">
          <column name="name"/>
      </property>
    <!--
       使用joined-subclass映射子类
         name="cn.itcast.extends02.HourEmployee":子类的类的完整路径
         table="h_emp":子类对应的表
    --> 

    <joined-subclass name="cn.itcast.extends02.HourEmployee" table="h_emp">
        <!--表示h_emp 表中的主键,同时又是外键-->
        <key column="hid"/>
        <property name="rate" column="rate" type="double"/>
    </joined-subclass>
    
    <joined-subclass name="cn.itcast.extends02.SalaryEmployee" table="s_emp">
        <key column="sid"/>
        <property name="salary" column="salary" type="double"/>
    </joined-subclass>
  </class>
  </hibernate-mapping>
*   子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中
*   在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。
2.1.删除员工信息

@Test
	public  void removeEmployee(){
		   Session session=sf.openSession();
		   Transaction tx=session.beginTransaction();
		   Employee e2=(Employee)session.get(Employee.class, 2);
		   session.delete(e2);
		   tx.commit();
		   session.close();
	}
*   删除员工信息,不用使用级联

2.2.查询唯一的员工,不是钟点工也不是正式员工

@Test
	public  void findUniqueEmployee(){
		   Session session=sf.openSession();
		   Transaction tx=session.beginTransaction();
		   //sql SELECT * FROM e_emp e WHERE e.id NOT IN(SELECT hid FROM h_emp) AND e.id NOT IN(SELECT sid FROM s_emp)
		   Query query=session.createQuery("from Employee e where e.id not in(select h.id from HourEmployee h) and e.id not in(select s.id from SalaryEmployee s)");
		   query.list();
		   tx.commit();
		   session.close();
	}

3.项目改造

 <!-- 加载映射文件-->
      <mapping resource="cn/itcast/add/Customer.hbm.xml"/>
      <mapping resource="cn/itcast/add/Order.hbm.xml"/>
*   在Hibernate配置文件加载映射文件

Customer.hbm.xml

 <class name="cn.itcast.add.Customer" table="customers" entity-name="customersk">
      <id name="id" type="integer">
        <column name="id"/>
        <generator class="increment"/>
      </id>
      <property name="name" type="string">
          <column name="name"/>
      </property>
      <set name="orderes" table="orders" inverse="true">
         <key>
           <column name="customer_id"/>
         </key>
          <one-to-many entity-name="ordersk"/>
      </set>      
   </class>
Order.hbm.xml
 <class name="cn.itcast.add.Order" table="orders" entity-name="ordersk">
      <id name="id" type="integer">
        <column name="id"/>
        <generator class="increment"/>
      </id>
      <property name="orderNumber" type="string">
          <column name="orderNumber"/>
      </property>
      <property name="price" type="double">
          <column name="price"/>
      </property>
     
      <many-to-one  name="customer" entity-name="customersk">
           <column name="customer_id"/>
      </many-to-one>
      
   </class>
*   entity-name:表示实体的名称  相当于起了一个别名

3.1.项目改造(保存save)

session.save("customersk",customer);
3.2.项目改在(修改

@Test
	public void updateCustomer(){
		CustomerDao customerDao=new CustomerDao();
		Customer customer=new Customer();
		customer.setId(1);
		customer.setName("西门公子");
		customerDao.updateCustomer(customer);
	}
*   这种方式的修改的是新建一个对象,再使用update方法,临时对象没有在一级缓存里面,每次都会有update语句,不管属性有没有变

3.3.项目改造(查询list)

public List<Customer> findCustomers() {
		Session session=null;
		Transaction tx=null;
		List<Customer> list=null;
		try {
			session=HibernateUtil.getSession();
			if(session!=null){
			   tx=HibernateUtil.beginTransaction(session);
			   Query query=session.createQuery("from customersk");
			   list=query.list();
			   
			   HibernateUtil.commitTransaction(tx);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		    //事务回滚
			HibernateUtil.rollbackTransaction(tx);
		}finally{
			HibernateUtil.closeSession(session);
		}
		
		return list;
	}
*   hql语句为from  customersk      customersk别名  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值