hibernate继承(转)
http://justsee.iteye.com/blog/1070588
一、继承关系_整个继承树映射到一张表
对象模型(Java类结构)
一个类继承体系一张表(subclass)(表结构)
Employee.java
- package com.taobao.hibernate.domain;
- public class Employee {
- private int id;
- private String name;
- private Department department;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Department getDepartment() {
- return department;
- }
- public void setDepartment(Department department) {
- this.department = department;
- }
- }
Skiller.java
- package com.taobao.hibernate.domain;
- public class Skiller extends Employee {
- private String skill;
- public String getSkill() {
- return skill;
- }
- public void setSkill(String skill) {
- this.skill = skill;
- }
- }
Sales.java
- package com.taobao.hibernate.domain;
- public class Sales extends Employee {
- private String sell;
- public String getSell() {
- return sell;
- }
- public void setSell(String sell) {
- this.sell = sell;
- }
- }<span style="white-space: normal;">
- </span>
这里我们考虑设计数据库是把员工都涉及在一张表,那么如何区分员工种类呢?加入员工类型这个字段来区别。
只需更改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 package="domain">
- <class name="Employee" discriminator-value="0">
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"></discriminator>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill" ></property>
- </subclass>
- <subclass name="Sales" discriminator-value="2">
- <property name="sell"></property>
- </subclass>
- </class>
- </hibernate-mapping>
<discriminator column="type" type="int"/>中的type默认值是string。
所有子类定义的字段不能为空。
使用了<discriminator column="type" type="int"></discriminator>这个标签,就是映射了type字段,然后Hibernate会根据type字段的值来确定从数据库中取过来的是什么对象。
在查询的get方法时,也可以自动识别,会自动用相对应的对象去封装数据。
一个继承树映射到一张表的话,会有很多空字段,不符合关系数据库的设计模式。
二、继承关系_每个类映射到一张表
这时候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 package="domain">
- <class name="Employee">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <joined-subclass name="Skiller">
- <key column="employee_id"></key>
- <property name="skill"></property>
- </joined-subclass>
- <joined-subclass name="Sales">
- <key column="employee_id"></key>
- <property name="sell"></property>
- </joined-subclass>
- </class>
- </hibernate-mapping>
<joined-subclass name="Sales">
子类对应类名为Sales,表名为Sales
<key column="employee_id"></key>
通过employee_id与Employee表关联
<property name="sell"></property>
设置sell属性
</joined-subclass>
这样就完成了Hibernate的配置,生成的表符合上面所说的表结构。
Hibernate: insert into Department (name) values (?)
插入部门
Hibernate: insert into Employee (name, dpt_id) values (?, ?)
插入销售员工到员工表
Hibernate: insert into Sales (sell, employee_id) values (?, ?)
插入销售员工到销售员工表
Hibernate: insert into Employee (name, dpt_id) values (?, ?)
插入技术员工到员工表
Hibernate: insert into Skiller (skill, employee_id) values (?, ?)
插入技术员工到技术员工表
5条插入信息
现在又有问题了,既然用到了多表关联,那么删除这些级联操作会怎么样呢
Hibernate: delete from Sales where employee_id=?
Hibernate: delete from Employee where id=?
发现两条delete语句很好的将员工信息删除掉了。
这里还需要注意的是,查询的时候避免使用多态查询,多表连接查询效率较低,最好明确指定查询的类别,不要直接用员工类进行查询。
三、继承关系_鉴别器与内连接相结合
把属性不多的类对应的列放到父类列中,把子类属性多的单独用一个表。这里假设Sales有很多列
内容和上两篇没有什么大的区别,原理类似,只是标签上略有不同。
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 package="domain">
- <class name="Employee" discriminator-value="0">
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"/>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill"></property> </subclass>
- <subclass name="Sales" <strong><span style="color: #ff0000;">discriminator-value="2"</span></strong>>
- <join table="sales">
- <key column="employee_id"></key>
- <property name="sell"></property>
- </join>
- </joined-subclass>
- </class>
- </hibernate-mapping>
四、继承关系_每.类映射一张独立表
可见表之间都是独立的,没有关联的。
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 package="domain">
- <class name="Employee">
- <id name="id">
- <generator class="hilo"/>
- </id>
- <property name="name"></property>
- <many-to-one name="dpt" column="dpt_id" lazy="false"></many-to-one>
- <union-subclass name="Skiller">
- <property name="skill"></property>
- </union-subclass>
- <union-subclass name="Sales">
- <property name="sell"></property>
- </union-subclass>
- </class>
- </hibernate-mapping>
这种方式的局限在于,如果一个属性在超类中做了映射,其字段名必须与所有子类表中定义的相同(Hibernate可能在后续版本中放宽此限制)。除此之外,使用union-subclass映射策略是不可使用identity的主键生成策略,因为同一类继承层次中所有实体类都需要使用同一个主键种子(即多个持续化实体对应的记录的主键是连续的)。受此影响,也不应该使用native主键生成策略,因为native会根据数据库来选择使用identity或sequence策略。,所以不要native,identity,sequence主键生成策略,可以是increment,hilo。
如果父类是abstract=”true”就不会有表与之对应。
隐式多态,映射文件没有联系,限制比较多很少使用。
hibernate继承(转)的更多相关文章
- 转Hibernate继承
hibernate继承映射 以下测试是在mysql中进行的. 1.单表方式 Animal.java @Entity @Inheritance(strategy=InheritanceType.SING ...
- 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法
几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...
- SSH开发实践part3:hibernate继承映射
0 大家好.上次讲了关于hibernate中双向1-N的映射配置,可以参考:http://www.cnblogs.com/souvenir/p/3784510.html 实际项目中,对象间的关系比较复 ...
- Hibernate继承映射
在面向对象的程序领域中,类与类之间是有继承关系的,例如Java世界中只需要extends关键字就可以确定这两个类的父子关系,但是在关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子 ...
- web进修之—Hibernate 继承映射(5)
先看三个类的继承关系,Payment是父类,CashPayment和CreditCardPayment是Payment的子类: view plaincopy to clipboardprint p ...
- Hibernate继承类的实现
版权声明:本文为博主原创文章,如需转载请标注转载地址. 博客地址:http://www.cnblogs.com/caoyc/p/5603724.html 对于继承关系类的映射.比如在论坛中文章(Ar ...
- hibernate 继承映射关系( SINGLE_TABLE)
三种继承映射关系. 1,SINGLE_TABLE person student teacher 在一个表中,student和teacher继承自person,通过一个Discriminato ...
- Hibernate 继承映射可能会遇到的错误
问题: 我们在配置hibernate的时候,默认是会配置下面的两个属性的 <property name="hibernate.default_catalog">hibe ...
- Hibernate继承注解
hibernate应用中,继承的用途或目的主要有两点: 组件化:故明思义,把重复性的代码抽取成组件,以便重用和维护.hibernate应用中,一些重复的字段,重复的映射配置,就需要抽取成组件. 多态性 ...
随机推荐
- html5 完整图片上传
<div class="photo" style="display:none;" id="upPhoto"><div cl ...
- OD使用教程3
reverseMe爆破: 跳转指令 让跳转已实现,把z的1改成0 按F8走,继续把z的1改成0,实现跳转 根据跳转指令,改变s或o,使跳转不实现 指令如上使跳转不实现 继续按f8往下走然后成功
- exp
想将远程机器上的数据库备份,搞了一上午,终于解决了: exp 用户名/密码@ip/service名 file=地址+文件名
- 异常处理和JDBC
1.异常: 格式:try{ 要执行的可能出现异常的语句 } catch(Exception e){ 对异常进行处理的语句 } finally{ 一定会被处理的语句 //可以不写 } 当需要 ...
- 禁止Visual Studio中的编译警告
VC编译器有个很蛋痛的自家警告系统,默认下各种开源库比如CGAL,各种4996,而一般自己写的 如sscanf,fopen这种单个文件,在文件头加个 #pragma warning (disable ...
- [转] How to change font settings for all UI elements (toolbar and context menus, property editors, etc.)
https://www.devexpress.com/Support/Center/Question/Details/S35762
- Mysql运行SQL文件 错误Incorrect table definition;there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
问题描述 想从服务器上DOWN下数据库.操作:先把数据库转存为SQL文件,然后在本地利用navicate运行SQL文件,出现错误信息: Incorrect table definition;there ...
- 强类型DataSet的使用简明教程
关于弱类型 DataSet的缺点: 无论何时从 DataSet检索值都是以Object类型返回,需要对它进行类型转换: 给其它开发者使用 时无法知道哪些列可用: 运行时才能知道所 有列名,数据绑定麻烦 ...
- 如何为Eclipse安装主题(Color Theme)
Eclipse开发环境默认都是白底黑字的,看到同事的Xcode中设置的黑灰色背景挺好看的,就去网上查了一下.发现Eclipse也可以设置主题. 方法1:你可以从Eclipse Marketplace中 ...
- CentOS7 bonding配置
操作系统:CentOS Linux release 7.1.1503 (Core) 网卡适配器: eno1.eno2 bonding类型:mode=1 (active-backup),主-备份策略 网 ...