Hibernate 继承映射实现方式之每个具体类对应一张表

现在有四个类Company、Employee、SalaryEmployee、HourlyEmployee,其中Employee是SalaryEmployee、HourlyEmployee的父类

类的实现代码如下:

public class Company  implements java.io.Serializable {


    // Fields    

     private Integer id;
     private String name;
     private Set Employees = new HashSet(0);
}

public class Employee  implements java.io.Serializable {


    // Fields    

     private Integer id;
     private String name;
     private Company company;
}

public class HourlyEmployee extends Employee implements java.io.Serializable {


    // Fields    

     private Double rate;
}

public class SalaryEmployee extendsEmployee implements java.io.Serializable {


    // Fields    

     private Double salary;
}
这四个类都省略了getter/setter方法,并且都是用Hibernate反向机制自动生成的。

该种实现Hibernate继承映射策略——每个具体对应一张表,上述的具体类就是HourlyEmployee和SalaryEmployee

首先设计下数据库,具体如下图:

company表

Hibernate 继承映射实现方式之每个具体类对应一张表_第1张图片


hourly_employee表



salary_employee表

Hibernate 继承映射实现方式之每个具体类对应一张表_第2张图片



hourly_employee和salary_employee表中的字段company_id为外键,参照company表中的id


配置company.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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.xkey.hibernate.bean.Company" table="company" catalog="hibernate">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="128" not-null="true" />
        </property>
        <set name="Employee1s" inverse="true" cascade="all" lazy="true">
            <key>
                <column name="company_id" not-null="true" />
            </key>
            <one-to-many class="com.xkey.hibernate.bean.Employee1" />
        </set>
    </class>
</hibernate-mapping>

配置Employee1.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">
	<!--
		Mapping file autogenerated by MyEclipse Persistence Tools
	-->
<hibernate-mapping>
	<class name="com.xkey.hibernate.bean.Employee1">
		<id name="id" type="java.lang.Integer">
			<column name="id" />
			<generator class="increment" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="name" length="128" not-null="true" />
		</property>

		<many-to-one name="company" class="com.xkey.hibernate.bean.Company"
			fetch="select">
			<column name="company_id" not-null="true" />
		</many-to-one>
		
		<union-subclass name="com.xkey.hibernate.bean.HourlyEmployee1"
		table="hourly_employee1" extends="com.xkey.hibernate.bean.Employee1">
		<property name="rate" type="java.lang.Double">
			<column name="rate" precision="10" scale="5"></column>
		</property>
		</union-subclass>
		<union-subclass name="com.xkey.hibernate.bean.SalaryEmployee1"
			table="salary_employee1" extends="com.xkey.hibernate.bean.Employee1">
			<property name="salary" type="java.lang.Double">
				<column name="salary" precision="10" scale="5"></column>
			</property>
		</union-subclass>
	</class>
	
</hibernate-mapping>
Employee1.hbm.xml中hourly_employee表和salary_employee表拥有的公共字段使用<property>,外键使用<many-to-one>,对于每个表特定的字段就使用<union-subclass>

具体就看上面的配置文件就可以了。

这里需要注意的是:使用<union-subclass>那么generator就不能使用class="identity",否则会报错:Cannot use identity column key generation with <union-subclass> mapping

还有一点就是<class name="com.xkey.hibernate.bean.Employee1">如果添加abstract属性的话,如果abstract="true"那么将不会生成表结构,如果abstract="false"那么将不会插入数据。个人觉得这个属性还是不要加的好。

在具体insert数据的时候会出现如下问题:

Company company = new Company("xkey",new HashSet());
		HourlyEmployee1 employee1 = new HourlyEmployee1("xukai",company,12.5);
		SalaryEmployee1 employee2 = new SalaryEmployee1("color",company,10000.0);

		company.getEmployee1s().add(employee1);
		company.getEmployee1s().add(employee2);
		
		CompanyDAO dao = new CompanyDAO();
		dao.save(company);
上面这段代码就是company、hourly_employee、salary_employee个插入一条数据,但是都是参照同一个company,这里在insert后会发现hourly_employee、salary_employee表中的主键id是不连续,具体是什么原因就需要去问Hibernate了,不用说也应该知道,问题肯定在session那里。

下图是我连续执行两次上述代码的结果


由于只有EmployeeDAO这一个DAO层访问数据库的方法,所以在查询的时候会很蛋疼,如果按照id来查询,那么查询出来的值究竟是hourly_employee表的数据还是salary_employee表呢,解决这个就需要调用返回值的类型来判断下。

综上所述,此种实现继承映射的方法个人觉得很蛋疼,还不如hourly_employee、salary_employee表个搞一个hbm.xml文件呢,这样对数据库的操作都将很方便,并且数据库存储的开销也和上面的方法相同,所以这种解决映射问题的方法不可取,大家就使用平常的方法就可以了。


还有其他两种解决映射问题的方法,将在后面介绍。


上面都是本人自己的见解,刚刚接触Hibernate,如果有说的不对的地方还望大家指正。


你可能感兴趣的:(Hibernate,数据库,MyEclipse,Integer,Class,generator)