【Hibernate步步为营】--继承映射具体解释
上篇文章讨论了多对多映射,在使用多对多映射时重点是使用<many-to-many>标签,并在标签的两端加入外键这样在生成关系时会创建两个关系之间的关系表,通过关系表来维护它们之间的关系,另外对于单向和双向的差别是在映射的哪一端加入标签的问题。在面向对象中非常重要的一个特性就是继承,继承实现了代码的复用,并且Hibernate把基本上全部的对象模型进行了映射封装,当中就包含继承映射,接下来就具体讨论。
一、继承映射
继承是面向对象非常重要的特性,它实现了代码的服用,在关系模型中相同也有继承关系,这样的继承关系事实上能够看做是一种枚举关系,一种类型中能够枚举出非常多子类型,这些子类型和父对象形成了继承关系,能够对其进行枚举的大部分都能够看做是一种继承映射,所以这样的枚举关系能够看做是继承映射,比如动物就是一种抽象类,它是其他动物猪、猫等的父类,它们之间就是一种继承关系,例如以下图:
这样的继承映射在转化为关系模型后会生成一张表,那么这张表是怎样区分这两种类型的呢?用的是关系字段,须要在表中加入类型字段,使用keyword来标明对象的类型。所以上图中的对象模型相应的表结构例如以下:
在生成表结构时,须要加入相应的字段类型,所以须要在映射文件里加入相应的映射鉴别器,这里就须要使用discriminator-value属性。
1.1、类文件
类文件里没有须要注意的地方,在编写时注意之间的继承关系就可以。
清单一:Animal类代码,仅仅须要加入主要的属性。
package com.src.hibernate;
public class Animal {
//id号
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//名称
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//性别
private boolean sex;
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
清单二:Bird和Pig类,加入主要的属性,并继承Animal类。
package com.src.hibernate;
public class Bird extends Animal { //高度
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
} } package com.src.hibernate;
public class Pig extends Animal { //重量
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
1.2、映射文件
映射文件里须要加入相应的映射,该模型中仅仅须要加入一个映射文件,由于仅仅生成一张表,在映射文件里加入相应的子类映射,使用<subclass>标签,标签中加入鉴别器discriminator-value,该鉴别器属性指明了在数据库中写入数据时指示写入的是何种类型,例如以下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.src.hibernate.Animal" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<!-- 增加鉴别标签,且必须放在id后面 -->
<discriminator column="type" />
<property name="name"/>
<property name="sex" type="boolean"/> <subclass name="com.src.hibernate.Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="com.src.hibernate.Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class> </hibernate-mapping>
1.3、分析结果
生成的mysql数据库表中不仅会加入Animal的基本属性,并且会加入Pig和Bird的属性,由于在映射文件里使用<subclass>写出了所加入的属性,另外还加入了相应的鉴别器属性,所以在数据库中会加入相应的鉴别列,生成的表结构例如以下图:
二、数据操作
2.1 写入数据
在进行数据读取和写入操作时须要注意类中的操作使用了
public void testSave(){
Session session=null;
try{
//创建session对象
session=HibernateUtils.getSession();
//开启事务
session.beginTransaction();
Pig pig=new Pig();
pig.setName("小猪猪");
pig.setSex(true);
pig.setWeight(200);
session.save(pig);
Bird bird=new Bird();
bird.setName("xiaoniaoniao");
bird.setSex(true);
bird.setHeight(100);
session.save(bird);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
2.2 多态查询--get和hql
前几篇文章已经讨论了主要的查询方法,仅仅须要使用load和get方法就可以,这里重点讨论多态查询。多态查询是指Hibernate在载入对象时可以採用instanceof鉴别出其真正的类型的对象就可以为多态查询。
Note:多态查询不支持延迟载入,也就是说假设使用load方法,须要在映射文件里将延迟载入设置为false。
2.2.1 load延迟载入
load支持延迟载入,在载入对象时事实上生成的是对象的代理,所以在使用多态查询时须要在映射文件里将延迟载入设置为false,例如以下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.src.hibernate.Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<!-- 增加鉴别标签,且必须放在id后面 -->
<discriminator column="type" />
<property name="name"/>
<property name="sex" type="boolean"/> <subclass name="com.src.hibernate.Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="com.src.hibernate.Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
</hibernate-mapping>
load载入方法,使用load载入该演示样例中支持多态查询,在配置文件里将延迟载入设置为false,所以这里使用load方法可以载入获得对应的对象类。
public void testLoad(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Animal ani=(Animal)session.load(Animal.class,1);
System.out.println(ani.getName());
//由于load默认支持lazy,所以我们看到的是Animal的代理
//所以採用了instanceof无法鉴别出真正的类型Pig
//所以load在此情况下是不支持多态查询的
if(ani instanceof Pig){
System.out.println("我是小猪猪!");
}else{
System.out.println("我不是小猪猪!");
}
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
2.2.2 hql查询
hql支持多态查询,这主要因为查询出的是一个真正的对象,并不会返回一个代理,所以hql支持多态查询,另外在查询时须要注意查询语句中不要使用表名,而是要使用类名称,Hibernate会依据类名称将其映射为相应的表名称,例如以下:
public void testLoad5(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
List<Animal> list=session.createQuery("from Animal").list();
for(Iterator iter=list.iterator();iter.hasNext();){
Animal a=(Animal)iter.next();
if(a instanceof Pig){
System.out.println("我是小猪猪!");
}else{
System.out.println("我不是小猪猪!");
}
}
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
查询结果:
Hibernate: select animal0_.id as id0_, animal0_.name as name0_, animal0_.sex as sex0_, animal0_.weight as weight0_, animal0_.height as height0_, animal0_.type as type0_ from t_animal animal0_
我是小猪猪!
我不是小猪猪!
我是小猪猪!
我不是小猪猪!
结语
继承映射是对象模型中重要的关系映射,通过使用继承映射可以将继承关系转换为相应的关系表,在配置映射文件时须要使用<subclass>标签,另外还须要在标签中加入鉴别器属性来标明不同的类型,在操作读取时才干非常快的鉴别出相应的类型。
【Hibernate步步为营】--继承映射具体解释的更多相关文章
- 【Hibernate步步为营】--映射合集汇总
前几篇文章具体讨论了对象模型到关系模型的转化方法,对映射关系做了具体的了解,Hibernate将对象模型转化为对应的关系模型是通过使用对应的映射来完毕的(相同也能够使用注解),对于对象之间的关系的转化 ...
- 初识Hibernate之继承映射
前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同的字段.例如: 如图,student表和teacher表共同具有id,nam ...
- hibernate笔记--继承映射关系的三种实现方式
单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...
- Hibernate配置文件和映射元素解释
象关系的映射是用一个XML文档来说明的.映射文档可以使用工具来生成,如XDoclet,Middlegen和AndroMDA等.下面从一个映射的例子开始讲解映射元素. AD:干货来了,不要等!WOT20 ...
- Hibernate之继承映射
1. Hibernate支持三种继承映射策略: –使用 subclass进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. –使用 j ...
- Hibernate的继承映射
对象模型示例: 继承映射的实现方式有以下三种: (一)每棵类继承树一张表 (二)每个类一张表 (三)每个子类一张表 (一)每棵类继承树一张表 关系模型如下: 映射文件如下: <hibernate ...
- hibernate中继承映射保存
1 简单继承映射,在子类上进行映射配置,可以将父类属性直接配置在子类映射文件中. 简单例子如下:teacher类继承自Person类. public class Person { private in ...
- hibernate映射-继承映射
对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate的继承映射可以理解成持久化类之间的继承关系.例如:人和学生之间的关系.学生继承人,可以认为学生是一个特殊的人,如果对人进 ...
- Hibernate4.x之映射关系--继承映射
Hibernate的继承映射可以理解为持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持以下三 ...
随机推荐
- JS操作DOM元素属性和方法
Dom元素基本操作方法API,先记录下,方便以后使用. W3C DOM和JavaScript很容易混淆不清.DOM是面向HTML和XML文档的API,为文档提供了结构化表示,并定义了如何通过脚本来访 ...
- C#操作word封装
在项目中添加Microsoft.Office.Interop.Word.dll引用 Codepublic class WordAPI{ private object _template; ...
- 运行phpize时出现:Cannot find autoconf. Please check your autoconf installation
运行/usr/local/webserver/php/bin/phpize时出现:Configuring for:PHP Api Version: 20041225Zend Module Api No ...
- 【HAOI2011】向量
[题目描述] 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个 ...
- PHP添加、更新solr索引
<?php $options = array ( 'hostname' => 'localhost', 'port' => '8080', 'path'=>'solr/help ...
- 07_RHEL7配置yum源
redhat 默认自带的 yum 源需要注册才能更新.想不花钱也可以更新,就需要替换掉redhat的yum源. 检查是否安装yum包 查看RHEL是否安装了yum,若是安装了,那么又有哪些yum包: ...
- JQuery在光标位置插入内容
(function($) { $.fn.extend({ insertAtCaret: function(myValue) { var $t = $(this)[0]; //IE if (docume ...
- 封装好的PHP分页类,简单好用--在开源看到的,取回来自己用
class Pagination 独立分页类 调用方式: $pagenation = new Pagination( 4, 10, 200 ); // 4(第一个参数) = currentPage, ...
- storm接入metaq时类不兼容错误 无法初始化MonitorLog
在实际的项目中,需要storm从metaq中读取数据,一开始就有日志问题,查到是storm/lib中的log4j-over-slf4j和slf4j-api.jar包的不兼容导致的,这些日志包使用时必须 ...
- mongodb 教程三
mongodb 实际上是保存json的数据的结构.当查询 是修改时 key 是可以用''保存. mongodb 插入语句 db.weixin.insert({name:'zhangfeng',age ...