hibernate继承(转)
2016-04-11 11:32
369 查看
http://justsee.iteye.com/blog/1070588
一、继承关系_整个继承树映射到一张表
对象模型(Java类结构)
一个类继承体系一张表(subclass)(表结构)
Employee.java
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
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
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代码
<?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代码
<?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代码
<?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代码
<?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”就不会有表与之对应。
隐式多态,映射文件没有联系,限制比较多很少使用。
一、继承关系_整个继承树映射到一张表
对象模型(Java类结构)
一个类继承体系一张表(subclass)(表结构)
Employee.java
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
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
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代码
<?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代码
<?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代码
<?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代码
<?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”就不会有表与之对应。
隐式多态,映射文件没有联系,限制比较多很少使用。
相关文章推荐
- Drawable的getIntrinsicHeight()和getIntrinsicWidth()
- EL表达式详细使用
- 集合之LinkedList
- 怎么实现EDIUS底屏游走字幕的制作
- EOF中空格和tab的问题
- 群—深入
- ios后台长时间运行
- JAVA 回调机制(callback)
- 【python】python for data analysis环境安装
- Python陷阱:tuple与Nonetype
- Java 改进简单加法器实现(代码精简)
- kvm 虚拟化 virsh shutdown 无法关闭客户机
- 排序算法之冒泡排序和选择排序
- 关于学习的一些思考
- CSS hack 技术
- WebKit for Developers
- MySQL5.7.11免安装版的安装和配置:解决MYSQL 服务无法启动问题
- android shape的使用
- [综合] 为什么要使用Unix时间戳
- 高通msm8994启动流程简介