0

  大家好。上次讲了关于hibernate中双向1-N的映射配置,可以参考:http://www.cnblogs.com/souvenir/p/3784510.html

  实际项目中,对象间的关系比较复杂,除了上次讲的相互关联以外,这次我们要讲的就是关于对象的继承。hibernate如何来通过配置完成对象的继承?

1

  比如有一个父类person,然后两个对应的子类,一个是teacher,一个是student。教师和老师除了拥有person这个类所有的属性以外,还会有一些自己独特的属性。

  hibernate提供的映射方法有三种:

  A 一个子类对应一个表

  也就是说每个子类对对应新建一张表,里面的属性都会加上父类的属性,然后再分别加上自己的单独的属性

  这样做无疑是增加了许多冗余,所以不推荐。

  B 用一张大表来表示所有子类的属性集合

  比如父类有3个公共属性,teacher这个子类有2个单独属性,student有3个单独属性,那么我们需要创建一张表,把这8个属性全部包括在内

  然后在通过一个字段来区分这些对象实体具体属于那一个子类

  C 父类表存储公共属性,每一个字表存储自己单独的属性,然后通过唯一ID进行关联

2  【用一张大表来表示所有子类的属性集合】

   还是用之前的employee对象来做演示,现在我们需要在employee下继承一个子类manager

    这个子类目前为了演示我们只添加一个单独的属性:部门

   来看看hibernate的配置文件:

  

<hibernate-mapping package="com.souvenir.bean">
<class name="Employee" table="Employee" discriminator-value="E">
<!-- 映射标识属性 -->
<id name="id" column="emp_id"
type="int">
<!-- 指定主键生成器策略 -->
<generator class="identity"/>
</id> <discriminator column="empType" type="string"></discriminator> <!-- 映射普通属性 -->
<property name="name" type="string"/>
<property name="password" type="string"/>
<property name="age" type="int"/> <!-- employee子类manager -->
<subclass name="Manager" extends="Employee" discriminator-value="M">
<property name="dept" type="string" length="50" column="dept_name"/>
</subclass>
</class>
</hibernate-mapping>

  需要说明一下的是:

  • 这种方式是通过 subclass  关键字来完成子类的配置
  • 父类需要 discriminator  关键字类指定区分的字段
  • 所有子类添加 discriminator-value 属性来区分其对象(如果父类需要的话也可以加上)  

  下面我们来测试一下映射的效果,具体的测试代码我就不写了,大概就是保存几个manager和employee对象

  

  通过数据库中结果可以看出,前10个是employee对象,empType都是E

  最后一个是manager对象,empType为M

  这种方式可以看出也是有很多的冗余字段,对于employee来说没有dept_name属性,所以这个属性都为null

3 【父类表存储公共属性,每一个字表存储自己单独的属性,然后通过唯一ID进行关联】

  这种情况下我们需要使用关键字 joined-subclass 来加入所有的子类,子类中除了需要配置单独的属性之外

  需要指定一个key,来与父类关联。(通过column属性)

  下面看一下上面修改的配置:

<hibernate-mapping package="com.souvenir.bean">
<class name="Employee" table="Employee" >
<!-- 映射标识属性 -->
<id name="id" column="emp_id"
type="int">
<!-- 指定主键生成器策略 -->
<generator class="identity"/>
</id> <!-- 映射普通属性 -->
<property name="name" type="string"/>
<property name="password" type="string"/>
<property name="age" type="int"/>
<!-- 与manager的关联关系 -->
<many-to-one name="manager" class="Manager" column="mgr_id" lazy="false"/> <!-- 映射和Payment之间的关联关系 -->
<set name="payments" inverse="true" lazy="false">
<key column="emp_id" />
<one-to-many class="Payment"/>
</set> <!-- employee子类manager -->
<joined-subclass name="Manager" extends="Employee" >
<key column="emp_id"></key>
<property name="dept" type="string" length="50" column="dept_name"/>
</joined-subclass>
</class>
</hibernate-mapping>

  注意这里就不再需要 discriminator 配置了。

  下面看一下测试效果:(对了,测试代码都不用变)

  首先数据库中有了两个表,一个是employee,一个是manager

  

   

  这里可以看出,所有公共属性都存在了父表中,而子表只是存储了其需要的属性,二者通过emp_id来关联。

4 继承对象的1-N关联

  像上面这种继承对象之间可否进行1-N的关联呢,答案是肯定的,而且在hibernate中的配置操作与一般的1-N没有什么差别。

  

<hibernate-mapping package="com.souvenir.bean">
<class name="Employee" table="Employee" >
<!-- 映射标识属性 -->
<id name="id" column="emp_id"
type="int">
<!-- 指定主键生成器策略 -->
<generator class="identity"/>
</id> <!-- 映射普通属性 -->
<property name="name" type="string"/>
<property name="password" type="string"/>
<property name="age" type="int"/>
<!-- 与manager的关联关系 -->
<many-to-one name="manager" class="Manager" column="mgr_id" lazy="false"/> <!-- 映射和Payment之间的关联关系 -->
<set name="payments" inverse="true" lazy="false">
<key column="emp_id" />
<one-to-many class="Payment"/>
</set> <!-- employee子类manager -->
<joined-subclass name="Manager" extends="Employee" >
<key column="emp_id"></key>
<property name="dept" type="string" length="50" column="dept_name"/>
<set name="employees" inverse="true" lazy="false">
<key column="emp_id"/>
<one-to-many class="Employee"/>
</set>
</joined-subclass>
</class>
</hibernate-mapping>

  和我们上一讲的配置一样,1端通过set进行配置,N端都过many-to-one进行配置。

  需要补充一下的就是inverse这个属性, inverse=true的含义: 由双向关联另一方维护该关联,己方不维护该关联(只能进行查询操作)。

  在本例中,manager中有inverse属性,也就是说对于employee与manager的关联关系是交由employee进行维护,manager只能进行查询操作。

  

        Manager manager=mgrDao.get(11);

        for(int i=1;i<=5;i++){
Employee emp=empDao.get(i);
emp.setManager(manager);
empDao.update(emp);
} Set<Employee> emps= manager.getEmployees();
for(Employee e:emps){
System.out.println("------"+e.getName());
}

  上面的测试代码,我们通过employee对象来配置其manager对象。

  然后通过manager来查找其对应的employee集合。

  

SSH开发实践part3:hibernate继承映射的更多相关文章

  1. 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法

    几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...

  2. hibernate 继承映射关系( SINGLE_TABLE)

    三种继承映射关系.   1,SINGLE_TABLE   person student  teacher 在一个表中,student和teacher继承自person,通过一个Discriminato ...

  3. Hibernate继承映射(@Inheritance)

    继承映射在 Annotation 中使用 @Inheritance 注解,并且需要使用 strategy 属性指定继承策略,继承策略有 SINGLE_TABLE.TABLE_PER_CLASS 和 J ...

  4. SSH开发实践part1:Spring与Hibernate整合

    1 之前把SSH看完了,现在从头开始进行项目实践.现在讲整个过程中的点滴记录下来,希望对后来者有参考. 2 SSH是一个轻量级的java开发框架,struts负责MVC开发模式中的controller ...

  5. SSH开发实践part4:Spring整合Struts

    1 好了,前面spring与hibernate的整合开发我们基本上讲完了,现在要开始服务层的开发,也就是处理事务的action,在这里我们需要引入spring与struts的整合.也就是将action ...

  6. SSH开发实践part2:双向1-N连接配置

    1 OK,上一篇已经介绍了项目开发的前期准备工作,具体内容可以参考:http://www.cnblogs.com/souvenir/p/3783686.html 按照开发步骤,我们现在已经可以开始进行 ...

  7. Hibernate继承映射

    在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子 ...

  8. web进修之—Hibernate 继承映射(5)

    先看三个类的继承关系,Payment是父类,CashPayment和CreditCardPayment是Payment的子类:   view plaincopy to clipboardprint p ...

  9. Hibernate 继承映射可能会遇到的错误

    问题: 我们在配置hibernate的时候,默认是会配置下面的两个属性的 <property name="hibernate.default_catalog">hibe ...

随机推荐

  1. 横屏下的ImagePickerController

    Try this way.... As per Apple Document, ImagePicker Controller never Rotate in Landscape mode. You h ...

  2. 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较

    2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...

  3. 防止被dylib hook的小技巧

    在Build Settings中找到“Other Linker Flags”在其中加上”-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null”即可.

  4. RHEL6.4找回root密码的方法

    1.先在系统启动的时候提示:press any key to enter menu 时按下e键(其实其他键也可以,只不过我习惯e键而已) 2.进入如下界面: 3.按上下箭头方向键选中第二项,按e键,进 ...

  5. Java基础学习总结--Java对象的序列化和反序列化

    一.序列化和反序列化的概念 把对象转换成字节序列的过程称之为对象的序列化 把字节序列恢复为对象的过程称之为对象的反序列化 对象序列化的主要用途: 1)把对象的字节序列永久的保存到硬盘上,通常放在一个文 ...

  6. cacti install on ubuntu

    安装cacti需要的软件需要 nginx + php + mysql + rrdtool + cacti + snmp 1.nginx 安装配置 首先按照如下命令安装,明显是马虎不细心./config ...

  7. LineNumberReader类

    开发人员常常会随手写一些类来读入一个简单的配置文件,或者用BufferedReader一行一行地读入特定格式的数据.这些随手写成的解析器往 往会提供基本的出错报告,但有时候它们会很难记录下出错的行号. ...

  8. web项目自动化测试方案预研

    一.  网上方案整理 Watir.Watir-Webdriver.Selenium2.QTP区别 Waitr与Watir-WebDriver有什么区别? Watir是非常优秀的一款自动化测试工具.其使 ...

  9. 学习ThinkPHP-1

    ThinkPHP 自建路由 关于文件关联 当在Applicatin\Home\Controller文件夹下建立一个控制器时如LoginController.class.php 在此文件夹下还有一个默认 ...

  10. 前端之JavaScript第三天学习(8)-JavaScript-对象

    JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等. 在 JavaScript 中,对象是拥有属性和方法的数据. 属性和方法 属性是与对象相关的值. 方法是能够在对象上执行的动 ...