`

第十二章 继承关系的映射

阅读更多
继承模型
在企业中经常会有员工的分类
我们在Java对象模型中可以使用继承的关系来实现,如下图:



 一张表映射
数据库中表的结构如下:


ID 姓名 地址 生日 开发人员技能 销售人员技能 员工类型
我们可以约定一种员工类型的规则,比如0普通员工,1开发人员,2销售人员

接下来,我们看一下Model层的实现和映射文件的编写:
Employee:
public class Employee {
protected String id;
protected String name;
protected String address;
protected Date birthday;

public Employee() {
super();
}

public Employee(String name, String address, Date birthday) {
super();
this.name = name;
this.address = address;
this.birthday = birthday;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}

Programmer:
public class Programmer extends Employee {
private String skill;

public Programmer(String name, String address, Date birthday, String skill) {
super(name, address, birthday);
this.skill = skill;
}

public Programmer() {
super();
}

public String getSkill() {
return skill;
}

public void setSkill(String skill) {
this.skill = skill;
}
}

Seller:
public class Seller extends Employee {
private String sell;

public Seller() {
super();
}

public Seller(String name, String address, Date birthday, String sell) {
super(name, address, birthday);
this.sell = sell;
}

public String getSell() {
return sell;
}

public void setSell(String sell) {
this.sell = sell;
}
}

映射文件:
<hibernate-mapping>
<class name="chapter5.model.Employee" table="employees"
discriminator-value="0">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<discriminator column="type" type="int" />
<property name="name" type="java.lang.String" column="name"
length="20" />
<property name="address" type="java.lang.String" column="address"
length="20" />
<property name="birthday" type="java.util.Date" column="birthday"
length="10" />
<subclass name="chapter5.model.Programmer" discriminator-value="1">
<property name="skill" type="java.lang.String" column="skill"
length="100" />
</subclass>
<subclass name="chapter5.model.Seller" discriminator-value="2">
<property name="sell" type="java.lang.String" column="sell"
length="100" />
</subclass>
</class>
</hibernate-mapping>
<discriminator column="type" type="int" />
鉴别器是给Hibernate来区分类型用的.就像listIndex是给list标签来记住元素顺序的作用是一样的,我们使用时不需要去理会这个字段,我们还是按我们平常的使用方式即可.

Dao层:
public class EmployeeDao {
public void create(Employee employee) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(employee);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public void delete(Employee employee) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.delete(employee);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public void update(Employee employee) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.update(employee);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public Employee findById(Serializable id) throws Exception {
Session session = null;
Employee employee = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
employee = (Employee) session.get(Employee.class, id);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return employee;
}
}
Test:
public class Test {
public static void main(String[] args) throws Exception {
EmployeeDao employeeDao = new EmployeeDao();

Employee employee = new Employee("张三", "武汉", new Date());
Programmer programmer = new Programmer("李四", "咸宁", new Date(),
"Java,sql,JS");
Seller seller = new Seller("李四", "襄樊", new Date(), "一流的销售技能");

employeeDao.create(employee);
employeeDao.create(programmer);
employeeDao.create(seller);
}
}
查找员工时应该注意要转型:
public class Test {
public static void main(String[] args) throws Exception {
EmployeeDao employeeDao = new EmployeeDao();
Employee employee = employeeDao
.findById("40285c8127d5f31b0127d5f31d4e0001");
System.out.println(employee.getName());
Programmer programmer = (Programmer) employeeDao
.findById("40285c8127d5f31b0127d5f31dbb0002");
System.out.println(programmer.getName() + ":" + programmer.getSkill());
Seller seller = (Seller) employeeDao
.findById("40285c8127d5f31b0127d5f31dcb0003");
System.out.println(seller.getName() + ":" + seller.getSell());
}
}

这种方法有个僻端:
可以看到数据库中,有很多空白的字段出现.


 解决方案:每个类映射到一张表
员工表:
ID 姓名 地址 生日

开发人员表
ID(主键,外键) 掌握的开发技能

销售人员表
ID(主键,外键) 掌握的销售技能

表之间的关系




类模型不动,主要改动配置文件即可.
Dao层也不动,Test也不动
配置文件改动如下:
<hibernate-mapping>
<class name="chapter5.model.Employee" table="employees">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="name" type="java.lang.String" column="name"
length="20" />
<property name="address" type="java.lang.String" column="address"
length="20" />
<property name="birthday" type="java.util.Date" column="birthday" />
<joined-subclass name="chapter5.model.Programmer"
table="programmer">
<key column="id" />
<property name="skill" type="java.lang.String" column="skill"
length="100" />
</joined-subclass>
<joined-subclass name="chapter5.model.Seller" table="seller">
<key column="id" />
<property name="sell" type="java.lang.String" column="sell"
length="100" />
</joined-subclass>
</class>
</hibernate-mapping>
<key column="id" /> id在这里即是主键又是外键, 和一对一关系差不多, 指定的是子表的ID
再运行一下Test文件的增加代码,可以看到生成了三张表.
运行一下查询代码,可以看到,查询是多表联合查询,在查询效率上比一张表要复杂一些,但是在表结构上却合理的多.

 第三种解决方案
鉴别器与子表接合方案
比如开发人员表中只有一个字段,销售人员表中有多个字段,那么为开发人员单独加一张表有点浪费,可以将开发人员表与普通员工表二合一,只需要单独为销售人员增加一张表即可.

只需要改动配置文件即可:


<hibernate-mapping>
<class name="chapter5.model.Employee" table="employees"
discriminator-value="0">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<discriminator column="type" type="int" />
<property name="name" type="java.lang.String" column="name"
length="20" />
<property name="address" type="java.lang.String" column="address"
length="20" />
<property name="birthday" type="java.util.Date" column="birthday" />
<subclass name="chapter5.model.Programmer"
discriminator-value="1">
<property name="skill" type="java.lang.String" column="skill"
length="100" />
</subclass>
<subclass name="chapter5.model.Seller" discriminator-value="2">
<join table="seller">
<key column="id" />
<property name="sell" type="java.lang.String" column="sell"
length="100" />
</join>
</subclass>
</class>
</hibernate-mapping>

 第四种解决方案:
每个类映射一张表
适用于公共字段较少的情况.
映射文件如下:
<hibernate-mapping>
<class name="chapter5.model.Employee" table="employees">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="name" type="java.lang.String" column="name"
length="20" />
<property name="address" type="java.lang.String" column="address"
length="20" />
<property name="birthday" type="java.util.Date" column="birthday" />

<union-subclass name="chapter5.model.Programmer" table="programmer">
<property name="skill" type="java.lang.String" column="skill"
length="100" />
</union-subclass>
<union-subclass name="chapter5.model.Seller" table="seller">
<property name="sell" type="java.lang.String" column="sell"
length="100" />
</union-subclass>
</class>
</hibernate-mapping>

以上就是解决继承的四种方案
  • 大小: 5.9 KB
  • 大小: 18.3 KB
  • 大小: 6.6 KB
  • 大小: 8.7 KB
分享到:
评论

相关推荐

    Java数据结构与算法中的源代码和applet - 站长下载

    第十二章迭代器 第十三章迭代器的实现 第十四章堆栈 第十五章队列与优先队列 第十六章二叉树 第十七章二叉树的应用 第十八章二叉搜索树 第十九章集与映射 第二十章有序集与映射的实现 第二十一章实现映射的散列法 第...

    Hibernate 3.6.0.Final Reference PDF 手册

    第 10 章 继承映射(Inheritance Mapping) 第 11 章 与对象共事 第 12 章 Read-only entities 第 13 章 事务和并发 第 14 章 拦截器与事件(Interceptors and events) 第 15 章 批量处理(Batch...

    UNIX环境高级编程(第十二章)

    第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 锁的隐含继承和释放 280 12.3.4 4.3+BSD的实现 281 12.3.5 建议性锁和强制性锁 284 12.4 流 ...

    精通Java Web整合开发(第2版)

    第12章 基于annotation注解技术的ssh 2整合开发 12.1 初识annotation522 12.2 亲身体验annotation的威力524 12.3 struts 2.x的annotation插件convention-plugin528 12.4 hibernate 3.x的annotation解决之道532 ...

    Entity Framework 6 Recipes(中文word翻译版)

    第12部分 查询之使用SQL语句 第13部分 查询之使用Entity SQL 第14部分 查询之查询中设置默认值和存储过程返回多结果集 第15部分 查询之与列表值比较和过滤关联实体 第16部分 查询之左连接和在TPH中通过派生类排序 第...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第12章 映射继承关系  12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第12章 映射继承关系  12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第12章 映射继承关系  12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第12章 映射继承关系  12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承...

    Java完美编程(第3版).pdf

    本书是为全英文版本。...第12章 uml和模式 第13章 借口和内部类 第14章 泛型和arraylist类 第15章 链式数据结构 第16章 稽核,映射和迭代器 第17章 初探swing  第18章 深入swing 第19章 java的发展永无止境

    Grails 技术精解与Web开发实践【源码+样章】----下载不扣分,回帖加1分,欢迎下载,童叟无欺

    第12章 与Spring整合 155 12.1 依赖注入与Spring容器基础 155 12.1.1 依赖注入 155 12.1.2 Spring容器基础 157 12.2 在Grails中使用Spring 158 12.3 本章小结 160 第13章 深入Controller 161 13.1 Controller中常用...

    C++编程思想习题

    第12章 动态对象创建 12.1对象创建 12.1.1C从堆中获取存储单元的方法 12.1.2运算符new 12.1.3运算符delete 12.1.4一个简单的例子 12.1.5内存管理的开销 12.2重新设计前面的例子 12.2.1仅从堆中创建string类 12.2.2...

    Java语言基础下载

    第十二章:高级I/O流 192 学习目标 192 I/O基础知识 193 字节流 193 字符流 194 节点流 194 过程流 194 基本字符流类 198 对象串行化 201 实例分析 203 内容总结 211 独立实践 212 第十三章:网络 213 学习目标 213 ...

    Hibernate实战(第2版 中文高清版)

     第12章 有效修改对象   12.1 传播性持久化   12.1.1 按可到达性持久化   12.1.2 把级联应用到关联   12.1.3 使用传播性状态   12.1.4 利用JPA的传播性关联   12.2 大批量和批量操作   12.2.1 使用...

    NHibernate中文文档

    第5章 集合类(Collections)映射 13 持久化集合类(Persistent Collections) 13 映射集合(Mapping a Collection) 13 值集合和多对多关联(Collections of Values and Many-To-Many Associations) 14 一对多关联(One-To-...

    hibernate学习笔记

    Hibernate的继承关系 21 每棵继承树映射成一张表(hibernate_extends_1) 22 每个子类映射成一张表(hibernate_extends_2) 24 每个具体类映射成一张表(hibernate_extends_3) 25 组件component映射(hibernate_...

    精通DirectX.3D图形与动画程序设计.pdf

    第12章 高级纹理技术 12.1 多层纹理映射 12.2 纹理阶段混合操作 12.2.1 黑暗映射 12.2.2 黑暗贴图动画 12.2.3 混合纹理与材质漫反射颜色 12.2.4 混合黑暗贴图与材质漫反射颜色 12.2.5 发光映射 12.2.6 细节映射 ...

    深入浅出MFC-简体版(2)PDF

    《深入浅出MFC》2/e 简体版 目录 ...第12章 打印与预览 第13章 多重文件与多重显示 第14章 MFC多线程程序设计 第15章 定制一个AppWizard 第16章 站上众人的肩膀——使用Components&activeX; Controls

Global site tag (gtag.js) - Google Analytics