- 浏览: 175557 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
xoxoj:
如果发现input输入框里包含这些全角的内容,jquery应该 ...
全角正则 -
TJYCHYANGCHENHUI:
不对吧!你的第一句话说错了好吧,在没有开启事务的情况下,sa ...
hibernate入门(三)Session中的主要方法 -
leonardleonard:
好帖
js公共函数(utils.js) -
xyqqjy:
朋友你和我的现状很像啊!
我离职快一年了,一直没有再做开发这一 ...
浮躁,我 -
djy1135:
确实需要静一下心! 一样一样来吧。 东西学不半扔了,跟没学差 ...
浮躁,我
3. 继承关系 :
在前面的部门员工实例中,我们设定的员工只是普通的员工,现在假如有Sale 和Skill 两类员工,它们作为Employee 的子类。如何实现这些子类的映射?为了方便以后的操作说明和不影响以前的操作,我们把前面用到的员工部门类及相关实体配置文件,主配置文件等拷贝到一个新的项目theExtend 下进行操作。
(1 )共享一张表:
意思是我们把子类的当作父类来处理共同映射成一张表。
>> 步骤一,创建Employee 的子类:Sale 和Skill 。内容如下:
package com.asm.hibernate.domain;
public class Sale extends Employee {
private String signSale ;
... 省略 getXXX setXXX()
}
package com.asm.hibernate.domain;
public class Skill extends Employee{
private String signSkill ;
... 省略 getXXX setXXX()
}
>> 步骤二、修改 Employee.hbm.xml 配置文件:
< hibernate-mapping package = "com.asm.hibernate.domain" >
< class name = "Employee" discriminator-value = "0" >
< id name = "id" >
< generator class = "native" />
</ id >
< discriminator column = "sign" type = "string" />
< property name = "name" ></ property >
< many-to-one name = "depart" column = "depart_id" />
< subclass name = "Sale" discriminator-value = "1" >
< property name = "signSale" ></ property >
</ subclass >
< subclass name = "Skill" discriminator-value = "2" >
< property name = "signSkill" ></ property >
</ subclass >
</ class >
</ hibernate-mapping >
配置文件说明 : 理解 <subclass> 元素: 它作为class 的子元素,但是它却和class 非常相似,name 同样是指所关联到的“类”,下面的 < property > 也与class 下的 < property > 一样。我们注意到它和class 均增加了一个新属性 discriminator-value ,它的作用就是配置这些类的“鉴别类型”。而 discriminator-value 的配置主要参照的是 <discriminator> , 它通常称为鉴别类型,即是说鉴别属于什么类型, 因为 在涉及到继承关系的操作时,总会涉及到父子类的关系,比如在上面的配置中,我们设定了sign 子段来标识类型,执行后会再对此作说明。 注意: < discriminator > 要写在后面元素的前面,因为它的dtd 文件是这样规定得。
>> 步骤三、修改主配置文件,由于是拷贝的前面的文件,所以需要去掉无关的映射文件,否则会提示找不到这此映射文件。
>> 步骤四、编写测试类:
package com.asm.hibernate.test;
public class ManyToOneTest {
public static void main(String[] args) {
add ();
Employee emp =query (2);
System. out .println( "emp type:" +emp );
}
static Employee query( int empId) {
Session s = null ;
try {
s = HibernateUtil.getSession ();
Employee emp = (Employee) s.get(Employee. class , empId);
System. out .println( "Department Name:" + emp.getDepart().getName());
return emp;
} finally {
if (s != null )
s.close();
}
}
static void add() {
Session s = null ;
Transaction tx = null ;
try {
Department depart = new Department();
depart.setName( "departName" );
Employee emp = new Employee();
emp.setName( "empName" );
emp.setDepart(depart);
Sale emp2 = new Sale();
emp2.setName( "saleEmployee" );
emp2.setSignSale( "saleName" );
emp2.setDepart(depart);
Skill emp3 = new Skill();
emp3.setName( "skillEmployee" );
emp3.setSignSkill( "skillName" );
emp3.setDepart(depart);
s = HibernateUtil.getSession ();
tx = s.beginTransaction();
s.save(emp);
s.save(emp2);
s.save(emp3);
s.save(depart);
tx.commit();
} finally {
if (s != null )
s.close();
}
}
}
说明:没的什么可多言的,只是要注意在查询时能返回其子类型。
下面来看执行后employee
表的内容:
+----+------+---------------+-----------+----------+-----------+
| id | sign | name | depart_id | signSale | signSkill |
+----+------+---------------+-----------+----------+-----------+
| 1 | 0 | empName | 1 | NULL | NULL |
| 2 | 1 | saleEmployee | 1 | saleName | NULL |
| 3 | 2 | skillEmployee | 1 | NULL | skillName |
+----+------+---------------+-----------+----------+-----------+
先来看sign
这列:由于sign
是鉴别类型设定的字段,且分别在前面为Employee
、Sale
、Skill
分别配置了“0
、1
、2
”所以它们会在sign
体现出来。其实
<
discriminator
column
=
"sign"
type
=
"string"
/>
也可以把type
属性值设为“int
”等。
再来看“signSale
、signSkill
”字段:它们本身是专为特定的类的属性配置的字段(比如在第一个<subclass>
元素下的property
子元素就配置了Sale
类的signSale
属性):所以它们只适合特定的类,而不适的类将会以null
来填充,这也就是如果采取“共享一张表”的最大缺点,它限制了我们不能在子类属性所映射的字段上设定“非空”。由于查询只涉及到一张表,所以效率较高。
(2 )每个子类一张附表:
意思是每个类均会有一张表,但是它不是完整的表,因为它的一些字段还在父类的表中。即是说:公共字段放在父表中,子类子类分别放在子类所映射的表中,它们之间采取主外键关联。这样解决了上面的“不能设定为空”的缺限。接上面只需修改 Employee.hbm.xml 配置文件,修改后的内容如下:
< class name = "Employee" >
< id name = "id" >
< generator class = "native" />
</ id >
< property name = "name" ></ property >
< many-to-one name = "depart" column = "depart_id" />
< joined-subclass name = "Sale" >
< key column = "sale_id" />
< property name = "signSale" />
</ joined-subclass >
< joined-subclass name = "Skill" >
< key column = "skill_id" />
< property name = "signSkill" />
</ joined-subclass >
</ class >
配置文件说明:当每个子类都会有一张表,在class 子元素下设定了 <joined-subclass> 元素, 它的意思就是专门指定为子类映射成一张表,特别要说明的是我们为每个子类都配置了<key> 元素,它的作用就是作为外键关联employee 表, 它的值也是参照class 元素的id 来生成。执行后的表内容如下:
skill 表 +----------+-----------+ | skill_id | signSkill | +----------+-----------+ | 3 | skillName | +----------+-----------+ |
sale 表 +---------+----------+ | sale_id | signSale | +---------+----------+ | 2 | saleName | +---------+----------+
|
employee 表
+----+---------------+-----------+
| id | name | depart_id |
+----+---------------+-----------+
| 1 | empName | 1 |
| 2 | saleEmployee | 1 |
| 3 | skillEmployee | 1 |
+----+---------------+-----------+
执行后请留意hibernate 产生的sql 语句。
(3 )联合使用表:
意思是同时使用(1
)(2
)的形式,主要目的是为了能使用鉴别类型,但同时也能“设定为非空”。同样只需要修改配置文件,修改后的内容如下:
<
class
name
=
"Employee"
discriminator-value
=
"0"
>
< id name = "id" >
< generator class = "native" />
</ id >
< discriminator column = "sign" type = "string" />
< property name = "name" ></ property >
< many-to-one name = "depart" column = "depart_id" />
< subclass name = "Sale" discriminator-value = "1" >
< property name = "signSale" ></ property >
</ subclass >
< subclass name = "Skill" discriminator-value = "2" >
< join table = "skill" >
< key column = "skill_id" />
< property name = "signSkill" />
</ join >
</ subclass >
</
class
>
观察上面的配置文件,不难发现我们对Sale
采取了(1
)方式,对Skill
采取了(3
)方式。同样请留意hibernate
的sql
语句和执行后的表。特别要说明的是:在进行操作时,由于hibernate
在进行操作时不能删除前面的相关联的表(主要是和第一种继承关系“共享一张表”时发生冲突,因为在建立的三张表,在未删除sale/skill
表时,是不能来删除employee
表,因为employee
表中的主键被另两张表关联了),所以需要手工删除表或者是直接删除数据库再建数据库。 补充:借助此例我们来看看
discriminator-value
的默认情况:如果我们在
<
subclass
name
=
"Skill"
discriminator-value
=
"2"
>
中不写
discriminator-value
配置,再来执行发现一切正常,查表发现它的sign
值为“com.asm.hibernate.domain.Skill
”即完整的类名,属于字串,所以执行正常。但当我们把
<discriminator>
中的type
属性改成int
时将会报错,因为默认不写是以完整的类名字串来作为标识,而设定type
为int,
所以将不能匹配类型。
(4 )每个具体类一张完整表:
与第(2 )种情况相比,它的主要特点就是为每个具体类建立一张表,表的字段对应子类本身的属性,同样也包括父类的所有属性。 同样只需要修改配置文件如下:
< class name = "Employee" >
< id name = "id" >
< generator class = "hilo" />
</ id >
< property name = "name" ></ property >
< many-to-one name = "depart" column = "depart_id" />
< union-subclass name = "Sale" >
< property name = "signSale" />
</union-subclass>
<union-subclass name="Skill">
<property name="signSkill" />
</union-subclass>
</class>
注意:id生成器选择了“hilo”,由于我们为每个具体类都映射了一张表,所以id不能只在每张表中递增,如果只在每张表中递增,这里的三张表中的id将会出现重复,这样我们在采用多态查询,将会查出多种结果,我们应让id是唯一的,所以采取了hilo的方式来生成id,它能保证id是全局性的递增生成,这样每张表中的id均不会重复。 同样请注意,可能需要删除某些表或者是删库建库才能执行测试类。 执行完成后,需留意hibernate产生的sql语句和表的结构内容。 补充说明:在使用这种方法时,如果父类为抽象类也是可行得,我们可以在<class>元素中配置abstract=”true”来说明父类为抽象类,自然就不会为其建表。
总结:在上面的继续关系中我们多次用到了删库建库,在执行测试类时,如果出现sql不能更新或者sql相关的错误,则不防尝试此方法。另外在学继承关系时,除了注意配置文件外,更应注意hibernate产生的sql语句以及执行后产生表的情况。通常我们建议表的数目不要超过类的数目。
发表评论
-
hibernate入门(十二)一些细节问题分析
2010-07-29 11:17 7121. 实体配置文件中的类型问题 : 在前 ... -
hibernate入门(十一)事务
2010-07-29 11:16 8931.事务引发的三层架构MVC讨论: 在前面的程序代码中多次用 ... -
hibernate入门(十)缓存
2010-07-29 11:11 6731. 模拟缓存并简要说明缓存实现原理 在myhib ... -
hibernate入门(九)关联关系中的高级应用_概述关联关系中的懒加载
2010-07-29 11:09 8005. 概述关联关系中的懒加载: (1) 一对 ... -
hibernate入门(九)关联关系中的高级应用_懒加载
2010-07-29 11:07 7134. 懒加载: 在前面我们已经对懒加载有所提及,现 ... -
hibernate入门(九)关联关系中的高级应用_inverse属性
2010-07-29 10:43 818inverse 的作用:询问是否放弃维护关系,默认是fals ... -
hibernate入门(九)关联关系中的高级应用_级联操作
2010-07-29 10:40 8211. 级联操作 : ... -
hibernate入门(八)其它集合类型
2010-07-29 10:38 782说明:在前面我们已经使用过set 集合类型,其实除了set ... -
hibernate入门(七)关联关系讨论_组件关系映射
2010-07-29 10:36 733典型实例:每个人有不同的名字,或者多个人可以是同一个名字,对于 ... -
hibernate入门(七)关联关系讨论_多对多关系映射
2010-07-29 10:31 741典型实例:一个学生可以有多个老师,同样一个老师可以有多个学生, ... -
hibernate入门(七)关联关系讨论_一对一关系映射
2010-07-29 10:27 882典型的实例:一个人有一个身份证,而一个身份证只属于某一个人。以 ... -
hibernate入门(七)关联关系讨论_一对多关系映射
2010-07-29 10:25 6652 .一对多关系映射: 上面提到的多个员工对应 ... -
hibernate入门(七)关联关系讨论_多对一关系映射
2010-07-29 10:22 7821 .多对一关系映射 : 一个部门有可以有多 ... -
hibernate入门(六)基本应用实例:Dao设计
2010-07-29 10:20 9671 .总体设计:设计User 对象及相关实体配置文件,工具 ... -
hibernate入门(五)完善工具类及HQL QBC初步相关
2010-07-29 10:17 10261 .无聊的讨论 : 在前面我们写了一个 ... -
hibernate入门(四)对象三种状态
2010-07-29 10:12 8301 .瞬时(transient ) ... -
hibernate入门(三)Session中的主要方法
2010-07-29 10:09 10441 .保存数据:save ,presist 说明 ... -
hibernate入门(二)优化代码
2010-07-29 10:07 7301 .为会么要优化 ... -
hibernate入门(一)第一个应用实例
2010-07-29 10:03 822一 、第一个应用实例 ...
相关推荐
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
案例目录: 01 01Hibernate_Handwork : 手工配置使用Hibernate,其中详细标了...07 07Hibernate_Mapping : Hibernate中的数据关联技术,是一个重点又是一个难点,演示了 一对一、多对一、一对多、多对多等几种情况。
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
是在是学习hibernate必备之;良材料 Hibernate基础入门,Hibernate基本API,Hibernate物件关联映射,继承映射和容器映射关系映射
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门; 2. 体系结构(Architecture); 3. 配置; 4. 持久化类(Persistent Classes); 5. 对象/关系数据库映射基础(Basic O/R Mapping); 6. 集合类(Collections)映射; 7. 关联关系映射; 8. 组件(Component)...
ORM及Hibernate介绍,包括ORM及Hibernate简介,Hibernate入门学习,Hibernate数据持久化,Hibernate缓存的使用,实体关联关系映射,实体继承关系映射,Hibernate查询语言
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. ...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
这个项目包括5个实体,这5个实体之间具有复杂的关联关系,而且业务逻辑也相对复杂,希望让读者理论联系实际,真正将jsf+ejb 3+jpa整合真正运用到实际开发中。该案例采用目前最流行、最规范的java ee架构,整个应用...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二...
43 Hibernate 关联映射 44 HQL实用技术 45 HQL高级 46 Criteria 查询 47-49 项目实战 影院信息查询系统 50 pl/sql 51 Oracle数据库对象 52 提高数据库性能 53 hibernate总结 54 使用Spring容器管理JavaBean 55 ...
5.2.1 GORM中的关联 5.2.1.1 一对一 5.2.1.2 一对多 5.2.1.3 多对多 5.2.2 GORM的组合 5.2.3 GORM的继承 5.2.4 集合、列表和映射 5.3 持久化基础 5.3.1 保存和更新 5.3.2 删除对象 5.3.3 级联更新和删除 5.3.4 立即...