HIBERNATE知识复习记录2-继承关系
发现了一篇和我类似的学习尚硅谷视频写的文章,内容如下,比我说的详细全面,可以看一下:
[原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
抄一段对三种继承关系的解释:
Java类中有继承关系,相应的在hibernate中,也有继承关系,子类反应到数据库中,就有多种实现形式了,子类和父类可以映射到同一张表中,子类也可以单独映射成一张表,但是用不同的标签实现,子类表和父类表的关系也不同。在映射文件中,有三个标签可以实现继承关系,分别是:subclass、joined-subclass、union-subclass,先陈述一下这三个标签的区别:
subclass标签就是为子类嵌入父类的表中而设计的,而且要指定鉴别器,即用subclass一定要有判断类型的一个列,鉴别器指定记录属于哪个类型。但是subclass也提供了为子类设置单独的表的功能,即join标签。但是不管是内嵌表还是外部表,都得指定鉴别器。
joined-subclass标签,提供的功能是只能为子类设定外部表,而且没有鉴别器,即子类一张表,父类一张表,子类以父类的主键为外键。父类对应的表中,没有判断类型的列。
注意:这两个标签不能混用,若是只想要内嵌表,或者是既想要有内嵌表,又想要外部表,又或者是只想要外部表,那么只能使用subclass标签,需要注意的是,不论哪种方式,都要指定鉴别器,即父类对应的表中,一定有一个判断类型的列;而若是只想要外部表,又不想在父类对应的表中,要那个判断类型的列,那么只能使用join-subclass。
union-subclass是将父类中的属性,添加到子类对应的表中去了。包括父类中的外键。union-class和前两个的区别就在于外键的不同,前两个标签,如果子类有单独对应的表的话,这个表的外键是其父类中的主键,而使用union-class,子类对应的表中的外键则和父类的外键是一样的,因为子类把父类继承的属性,也加到了自己的表当中。这样子类和父类的地位就相当了。不过这不是一种好的理解方式。如果是这样的话,那么就可以把父类设为抽象的类,并且在映射文件中,把父类设置为abstract="true",那么就不会再数据库中生成父类对应的表了,父类就只起到一个抽象的作用了。
下面看一下简单的例子:
subclass:
Person类
package subclass;
public class Person {
private Integer id;
private String name;
private int age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student类
package subclass;
public class Student extends Person {
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-23 15:37:20 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="subclass">
<class name="Person" table="PERSON" discriminator-value="person"> <!-- Person对象对应的辨别者列的值 -->
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<!-- 辨别者列 -->
<discriminator column="TYPE" type="string"></discriminator>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="int">
<column name="AGE" />
</property> <subclass name="Student" discriminator-value="student"> <!-- Student对象对应的辨别者列的值 -->
<property name="school" type="string" column="SCHOOL"></property>
</subclass>
</class>
</hibernate-mapping>
会生成一张表,包括父类和子类的所有字段,用一个辨别者列来区分是父类还是子类的数据,当为父类数据时,相应的子类数据为null。
HibernateTest类
package subclass; import java.util.List; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest {
private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before
public void init()
{
System.out.println("init"); // 1. 创建一个SessionFactory对象
sessionFactory = null;
Configuration configuration = new Configuration().configure(); // before 4.0
// sessionFactory = configuration.buildSessionFactory(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2. 创建一个Session 对象
session = sessionFactory.openSession(); // 3. 开启事务
transaction = session.beginTransaction(); } @After
public void destory()
{
System.out.println("destory");
// 5. 提交事务
transaction.commit(); // 6. 关闭Session
session.close(); // 7. 关闭SesssionFactory
sessionFactory.close();
} /**
* 缺点:
* 1. 使用了辨别者列
* 2. 子类独有的字段不能添加非空约束
* 3. 若继承层次较深,数据表的字段也会较多
*/ /*
* 插入操作:
* 1. 对于子类对象只需把记录插入到一张数据表中。
* 2. 辨别者列有Hibernate自动维护。
*/
@Test
public void testSave()
{
Person person = new Person();
person.setAge(11);
person.setName("AA"); session.save(person); Student stu = new Student();
stu.setAge(22);
stu.setName("BB");
stu.setSchool("ATGUIGU"); session.save(stu);
} /*
* 查询:
* 1. 查询父类记录,只需要查询一张数据表
* 2. 对于子类记录,也只需要查询一张数据表
*/
@Test
public void testQuery()
{
List<Person> persons = session.createQuery("FROM Person").list();
System.out.println(persons.size()); List<Student> stus = session.createQuery("FROM Student").list();
System.out.println(stus.size());
} }
joined-subclass:
Person类
package joinedclass;
public class Person {
private Integer id;
private String name;
private int age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student类
package joinedclass;
public class Student extends Person {
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-23 15:37:20 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="joinedclass">
<class name="Person" table="PERSON">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="int">
<column name="AGE" />
</property> <joined-subclass name="Student" table="STUDENT">
<key column="STUDENT_ID"></key> <!-- 和其父类一样的共有主键 -->
<property name="school" type="string" column="SCHOOL"></property>
</joined-subclass>
</class>
</hibernate-mapping>
使用joined-subclass会生成两张表, 并且对应的相关记录主键是相同的。
HibernateTest类
package joinedclass; import java.util.List; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest {
private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before
public void init()
{
System.out.println("init"); // 1. 创建一个SessionFactory对象
sessionFactory = null;
Configuration configuration = new Configuration().configure(); // before 4.0
// sessionFactory = configuration.buildSessionFactory(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2. 创建一个Session 对象
session = sessionFactory.openSession(); // 3. 开启事务
transaction = session.beginTransaction(); } @After
public void destory()
{
System.out.println("destory");
// 5. 提交事务
transaction.commit(); // 6. 关闭Session
session.close(); // 7. 关闭SesssionFactory
sessionFactory.close();
} /**
* 优点:
* 1.不需要使用辨别者列,
* 2.子列独有的字段能添加非空约束
* 3.没有冗余的字段
*/ /*
* 插入操作:
* 1. 对于子类对象至少需要插入到两张表中
*/
@Test
public void testSave()
{
Person person = new Person();
person.setAge(11);
person.setName("CC"); session.save(person); Student stu = new Student();
stu.setAge(22);
stu.setName("DD");
stu.setSchool("1-ATGUIGU"); session.save(stu);
} /*
* 查询:
* 1. 查询父类记录,做一个左外连接查询
* 2. 对于子类记录,做一个内连接查询
*/
@Test
public void testQuery()
{
List<Person> persons = session.createQuery("FROM Person").list();
System.out.println(persons.size()); List<Student> stus = session.createQuery("FROM Student").list();
System.out.println(stus.size());
} }
union-subclass:
Person类
package unionclass;
public class Person {
private Integer id;
private String name;
private int age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student类
package unionclass;
public class Student extends Person {
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-23 15:37:20 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="unionclass">
<class name="Person" table="PERSON">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="hilo" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="int">
<column name="AGE" />
</property> <union-subclass name="Student" table="STUDENT">
<property name="school" column="SCHOOL" type="string"></property>
</union-subclass>
</class>
</hibernate-mapping>
使用union-subclass会生成两张表,子表包含父表的所有信息,两张表没有关联,但子表会包含父表中的列,产生大量的重复列。
HibernateTest类
package unionclass; import java.util.List; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest {
private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before
public void init()
{
System.out.println("init"); // 1. 创建一个SessionFactory对象
sessionFactory = null;
Configuration configuration = new Configuration().configure(); // before 4.0
// sessionFactory = configuration.buildSessionFactory(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2. 创建一个Session 对象
session = sessionFactory.openSession(); // 3. 开启事务
transaction = session.beginTransaction(); } @After
public void destory()
{
System.out.println("destory");
// 5. 提交事务
transaction.commit(); // 6. 关闭Session
session.close(); // 7. 关闭SesssionFactory
sessionFactory.close();
} /**
* 优点:
* 1.不需要使用辨别者列,
* 2.子列独有的字段能添加非空约束
* 缺点:
* 1. 存在冗余的字段
* 2. 若更新父表的字段,更新的效率较低
*/ /*
* 插入操作:
* 1. 对于子类对象需要插入到一张表中
*/
@Test
public void testSave()
{
Person person = new Person();
person.setAge(11);
person.setName("CC"); session.save(person); Student stu = new Student();
stu.setAge(22);
stu.setName("DD");
stu.setSchool("1-ATGUIGU"); session.save(stu);
} /*
* 查询:
* 1. 查询父类记录,需把父表和子表记录汇总到一起
* 2. 对于子类记录,只需要查询一张数据表
*/
@Test
public void testQuery()
{
List<Person> persons = session.createQuery("FROM Person").list();
System.out.println(persons.size()); List<Student> stus = session.createQuery("FROM Student").list();
System.out.println(stus.size());
} @Test
public void testUpdate()
{
String hql = "UPDATE Person p SET p.age = 20";
session.createQuery(hql).executeUpdate();
}
}
HIBERNATE知识复习记录2-继承关系的更多相关文章
- HIBERNATE知识复习记录3-关联关系
先上一张图,关于几种关系映射: 抄一段解释: 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用.关联关系分为上述七 ...
- HIBERNATE知识复习记录1-连接及常用方法
要去面试了,复习一下HIBERNATE的相关知识吧,原来边看视频边写的代码如下,已经分不清先后次序了,大致看一看吧. 先看下总的配置文件hibernate.cfg.xml: <?xml vers ...
- HIBERNATE知识复习记录4-HQL和QBC
Hibernate中共提供了三种检索方式:HQL(Hibernate Query Language).QBC.QBE(Query By Example). HQL 是Hibernate Query L ...
- [原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
1.继承映射 举例:对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一 ...
- Hibernate学习---第八节:继承关系的映射配置
1.单表继承 (1).实体类,代码如下: package learn.hibernate.bean; import java.util.Date; /** * 持久化类设计 * 注意: * 持久化类通 ...
- 【Hibernate框架】三种继承映射
一.综述 大家都知道,hibernate作为ORM框架的一个具体实现,最大的一个优点就是是我们的开发更加的能体现出"面向对象"的思想.在面向对象开发中,类与类之间是可以相互继承的( ...
- hibernate映射的 关联关系:有 一对多关联关系,一对一关联关系,多对多关联关系,继承关系
hibernate环境配置:导包.... 单向n-1:单向 n-1 关联只需从 n 的一端可以访问 1 的一端 <many-to-one> 元素来映射组成关系: name: 设定待映射的持 ...
- Hibernate笔记——表的的4种继承关系
原文:http://justsee.iteye.com/blog/1070588 ===================================== 一.继承关系_整个继承树映射到一张表 对象 ...
随机推荐
- 7 无线wifi传输视频开发
转载,侵删 7 无线wifi传输视频开发 MT7601的驱动源码提供了两种:AP模式和STA模式源码.此时我使用USB作为AP热点,电脑作为STA模式,并使用ORTP实现无线传输视频 7.1.AP模式 ...
- FastAdmin 怎么把模块设置默认的首页?
F4NNIU: 参考 ThinkPHP5 的路由设置. fangke-河南: 或者看config.php Karson:需要把插件设置为默认首页吗?在后台就可以,设置他插件的为伪静态,即可.
- Apache+modproxy布置tomcat集群
一.环境: Apache: 2.2.14: 下载地址:http://archive.apache.org/dist/httpd/binaries/win32/ Tomcat: 7.0.82 JDK1. ...
- Angular 4 绑定
一.事件绑定 1. 创建doOnClick函数 2. 网页中绑定doOnClick方法 3. 效果图 二. 属性绑定 1. 定义imgUrl的网址 2. 定义img src属性 另外一种写法 3. ...
- android 开源项目列表【持续整理中。。。】
Android完整的开源项目,不包括各种组件的项目 社区客户端 oschina客户端:oschina网站的客户端,wp版,iOS版都有开源,一个社区型客户端,包括登录刷新各类视线 四次元新浪微博客户端 ...
- Linux内核编译:很少有人提及的一些内容
1. 你可以使用O=参数将编译结果放到其他位置(非源代码目录),例如:make O=~/build ... 这样做的好处是你的源代码目录不会受到任何改变:你甚至可以在不同的体系结构间共享源代码. 注意 ...
- 【比特币】SPV是如何工作的
SPV是如何工作的 SPV, Bloom 过滤器和检查点 这是一篇技术文章,获取比特币的工作知识. 一个完整的节点,比如比特币核心,知道以下几点: 每一个当前正在围绕网络广播事务处理 每一个曾经被送到 ...
- binlog之四:mysql中binlog_format模式与配置详解,binlog的日志格式详解
mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复 ...
- python + docker, 实现天气数据 从FTP获取以及持久化(五)-- 利用 Docker 容器化 Python 程序
背景 不知不觉中,我们已经完成了所有的编程工作.接下来,我们需要把 Python 程序 做 容器化 (Docker)部署. 思考 考虑到项目的实际情况,“持久化天气”的功能将会是一个独立的功能模块发布 ...
- Java Internet
网络通信: 网络通信三要素: IP 协议 端口 TCP: 建立连接,发送速度慢 三次握手协议 UDP: 不需要建立连接,发送速度快 安全性低 a) 使用UDP实现数据的发送 1 创建Socket端点实 ...