zoukankan      html  css  js  c++  java
  • Hebernate -- 映射继承关系

    1. Employee 为基类, 派生出HourEmployee 和 SalaryEmployee两个类。

    采用 subclass 元素的继承映射(1)

    采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表
    因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为辨别者列(discriminator).
    在这种映射策略下,使用 subclass 来映射子类使用class subclass discriminator-value 属性指定辨别者列的值
    所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中

    示例代码::

    Employee.java

    public class Employee {
    	private Integer id;
    	private String name;
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    }

    HourEmployee.java

    /**
     * 钟点工
     */
    public class HourEmployee  extends Employee{
    	
    	private Double rate;
    
    	public Double getRate() {
    		return rate;
    	}
    
    	public void setRate(Double rate) {
    		this.rate = rate;
    	}
    }
    

    SalaryEmployee.java

    /**
     * 正是员工
     */
    public class SalaryEmployee extends Employee {
     
    	private Double salary;
    
    	public Double getSalary() {
    		return salary;
    	}
    
    	public void setSalary(Double salary) {
    		this.salary = salary;
    	}	
    }

    Employee.hbm.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     <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>

    App.java

    public class App {
    	private static  SessionFactory sf=null;
    	
    	static{
    		   Configuration config=new Configuration();
    	       config.configure("cn/itcast/extends01/hibernate.cfg.xml");
    	       config.addClass(Employee.class);
    	       sf=config.buildSessionFactory();
    	}
    	
        /*
         * 知识点1: 保存员工信息
         */
    	@Test
    	public  void saveStudentAndCoure(){
    		   Session session=sf.openSession();
    		   Transaction tx=session.beginTransaction();
    		 
    		   Employee e=new Employee();
    		   e.setName("xxxx");
    		   
    		   
    		   HourEmployee he=new HourEmployee();
    		   he.setName("小昭");
    		   he.setRate(10d);
    		   
    		   SalaryEmployee se=new SalaryEmployee();
    		   se.setName("赵敏");
    		   se.setSalary(3000d);
    		   
    		   
    		   session.save(e);
    		   session.save(he);
    		   session.save(se);
    		   
    		   tx.commit();
    		   session.close();
    	}
    	
    	//知识点2: 查询钟点工信息
    	@Test
    	public  void findHourEmployee(){
    		   Session session=sf.openSession();
    		   Transaction tx=session.beginTransaction();
    		   //HQL语句 可以使用子类HourEmployee
    		   Query query=session.createQuery("from HourEmployee");
    		   query.list();
    		 
    		   
    		   tx.commit();
    		   session.close();
    	}
    	
    }

    hibernate.cfg.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
       <session-factory>
          <property name="hibernate.connection.username">root</property>
          <property name="hibernate.connection.password">root</property>
          <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
          <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
          
          <!-- 配置数据库的方言,让hibernate知道连接的是哪个数据库-->
          <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
       
          <!-- 配置利用javaBean和映射文件生成数据库中的表
               hibernate.hbm2ddl.auto值
                  * create:执行时,先查找该表是否存在,如存在先删除表,在创建表
                  * none:不能创建表,只能往表中插入数据,如表不存在抛出异常,默认值
                  * update:执行时,
                              情况一:
                                    先查找该表是否存在,如果表存在,直接插入,如果表不存在,先创建表,再插入数据.
                              情况二:
                                    先查找该表是否存在,如果表存在,但表的结构不一样,要修改表的结构
           -->
          <property name="hibernate.hbm2ddl.auto">update</property>
          
          <!-- 显示hibernate生成的sql语句 -->
          <property name="hibernate.show_sql">true</property>
       
          <!-- 显示格式化得sql语句 -->
          <property name="hibernate.format_sql">false</property>
          
       </session-factory>
    </hibernate-configuration>	


    采用 joined-subclass 元素的继承映射(2)


    采用 joined-subclass 元素的继承映射可以实现每个子类一张表
    采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。
    在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键该主键必须与父类标识属性的列名相同。但如果继承树的深度很深,可能查询一个子类实例时,需要跨越多个表,因为子类的数据一次保存在多个父类中。
    子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中

    代码示例: 未贴出的和(1)相同

    Employee.hbm.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     <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>    

    App.java

    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    
    public class App {
    	private static  SessionFactory sf=null;
    	
    	static{
    		   Configuration config=new Configuration();
    	       config.configure("cn/itcast/extends02/hibernate.cfg.xml");
    	       config.addClass(Employee.class);
    	       sf=config.buildSessionFactory();
    	}
    	
        /*
         * 知识点1: 保存员工信息
         */
    	@Test
    	public  void saveStudentAndCoure(){
    		   Session session=sf.openSession();
    		   Transaction tx=session.beginTransaction();
    		 
    		   Employee e=new Employee();
    		   e.setName("xxxx");
    		   
    		   
    		   HourEmployee he=new HourEmployee();
    		   he.setName("小昭");
    		   he.setRate(10d);
    		   
    		   SalaryEmployee se=new SalaryEmployee();
    		   se.setName("赵敏");
    		   se.setSalary(3000d);
    		   
    		   
    		   session.save(e);
    		   session.save(he);
    		   session.save(se);
    		   
    		   tx.commit();
    		   session.close();
    	}
    	
    	//知识点2: 查询钟点工信息
    	@Test
    	public  void findHourEmployee(){
    		   Session session=sf.openSession();
    		   Transaction tx=session.beginTransaction();
    		   //可以使用子类
    		   Query query=session.createQuery("from HourEmployee");
    		   query.list();
    		 
    		   tx.commit();
    		   session.close();
    	}
    	
    	//知识点5: 查询员工信息
    	@Test
    	public  void findEmployee(){
    		   Session session=sf.openSession();
    		   Transaction tx=session.beginTransaction();
    		   //可以使用子类
    		   Query query=session.createQuery("from Employee");
    		   query.list();
    		 
    		   tx.commit();
    		   session.close();
    	}
    
    	//知识点6: 删除员工信息(不用使用级联) 删除2号员工
    	@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();
    	}
    	
    	//知识点7:查询唯一的员工,不是钟点工也不是正式员工
    	@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();
    	}
    }





     

  • 相关阅读:
    Android网络编程要学的东西与Http协议学习
    数据存储与访问之——初见SQLite数据库
    ViewPager基础入门
    调用android方法,出现版本太低解决方法
    Android Studio 代码自动提示无效
    策略模式
    C#通过SendARP()获取WinCE设备的Mac网卡物理地址
    简单理解和使用 C# 委托与事件
    Oracle SQL developer客户端 如何连接已经安装完毕的Oracle服务器端
    源码分析之Map(二)HashCode详解
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3647998.html
Copyright © 2011-2022 走看看