Hibernate深入学习(三):继承与多态查询,joined-subclass与union-subclass
2016-06-22 18:02
337 查看
在上一篇中,我们对hibernate中3种继承有了初步了解,并对subclass进行了测试,以及知道了它的诸多缺点,这些缺点导致subclass在开发中并不常用,接下来我们看看剩下的两种继承方式:joined-subclass与union-subclass
本文中使用的实体类与测试代码同前篇,不再赘述
首先我们看看joined-class的实体映射文件:主要看元素
我们已经知道joined-subclass是会产生两张表的,中的table用于指定子类表名,并且使用person_id来与父类表建立关联
测试代码见前篇,插入的测试结果如下:
可以看到发出了4条sql语句,除了第一句省略,其它共3条insert语句
因为joined-subclass采用的是父类表存储父类字段,子类表存储子类字段,用外键关联,
因此第一条insert语句对应的是session.save(person);
第二天insert语句是在 session.save(worker)时,将worker继承自父类的字段插入,
最后一条insert语句是插入将worker插入到子类表中,它直插入子类独有的字段
在做查询时,请使用类全名的形式,例如:
查询的结果如下:
可以看出查询父类使用的是一个左外连接查询,同时查询出了子类,而查询子类使用的是一个内连接查询
最后一个是union-subclass,它和joined-subclass类似,它将父类对应一张表,子类对应一张表,此时的子类表包括了从父类中继承的字段,它的实体映射文件如下:注意看
可以看出union-subclass只需要指定一个表名即可
插入测试结果很简单,就是发出两条inert语句,插入到对应的表中即可
查询结果如下(hql也要使用类全名)
我们着重看一下父类的查询sql,比较有意思,它也将子类查询出来了,它先通过union将两张表联合查询,再从联合查询的结果中获取结果。
最后分析下二者的缺点:
1.插入与查询的效率都低下
2.union-subclass在更新父类表时效率低下
本文中使用的实体类与测试代码同前篇,不再赘述
首先我们看看joined-class的实体映射文件:主要看元素
<?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="cn.sina.join.subclass" auto-import="false"> <class name="Person" table="joined_person"> <id name="id" column="pid" length="10" type="java.lang.Integer"> <generator class="increment"></generator> </id> <property name="name" type="java.lang.String" length="32" not-null="true"></property> <property name="age" type="java.lang.Integer" length="5" not-null="true"></property> <joined-subclass name="Worker" table="joined_worker"> <key column="person_id"></key> <property name="job" type="java.lang.String" length="32"></property> <property name="unit" type="java.lang.String" length="32"></property> </joined-subclass> </class> </hibernate-mapping>
我们已经知道joined-subclass是会产生两张表的,中的table用于指定子类表名,并且使用person_id来与父类表建立关联
测试代码见前篇,插入的测试结果如下:
Hibernate: select max(pid) from joined_person Hibernate: insert into joined_person (name, age, pid) values (?, ?, ?) Hibernate: insert into joined_person (name, age, pid) values (?, ?, ?) Hibernate: insert into joined_worker (job, unit, person_id) values (?, ?, ?)
可以看到发出了4条sql语句,除了第一句省略,其它共3条insert语句
因为joined-subclass采用的是父类表存储父类字段,子类表存储子类字段,用外键关联,
因此第一条insert语句对应的是session.save(person);
第二天insert语句是在 session.save(worker)时,将worker继承自父类的字段插入,
最后一条insert语句是插入将worker插入到子类表中,它直插入子类独有的字段
在做查询时,请使用类全名的形式,例如:
session.createQuery("from cn.sina.join.subclass.Person").list();
查询的结果如下:
Hibernate: select person0_.pid as pid1_, person0_.name as name1_, person0_.age as age1_, person0_1_.job as job2_, person0_1_.unit as unit2_, case when person0_1_.person_id is not null then 1 when person0_.pid is not null then 0 end as clazz_ from joined_person person0_ left outer join joined_worker person0_1_ on person0_.pid=person0_1_.person_id Hibernate: select worker0_.person_id as pid1_, worker0_1_.name as name1_, worker0_1_.age as age1_, worker0_.job as job2_, worker0_.unit as unit2_ from joined_worker worker0_ inner join joined_person worker0_1_ on worker0_.person_id=worker0_1_.pid [Person [id=1, name=tom, age=10], Worker [job=washer, unit=bj], Person [id=3, name=tom, age=10], Worker [job=washer, unit=bj]] [Worker [job=washer, unit=bj], Worker [job=washer, unit=bj]]
可以看出查询父类使用的是一个左外连接查询,同时查询出了子类,而查询子类使用的是一个内连接查询
最后一个是union-subclass,它和joined-subclass类似,它将父类对应一张表,子类对应一张表,此时的子类表包括了从父类中继承的字段,它的实体映射文件如下:注意看
<?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="cn.sina.union.subclass" auto-import="false"> <class name="Person" table="union_person"> <id name="id" column="pid" length="10" type="java.lang.Integer"> <generator class="increment"></generator> </id> <property name="name" type="java.lang.String" length="32" not-null="true"></property> <property name="age" type="java.lang.Integer" length="5" not-null="true"></property> <union-subclass name="Worker" table="union_worker"> <property name="job" type="java.lang.String" length="32"></property> <property name="unit" type="java.lang.String" length="32"></property> </union-subclass> </class> </hibernate-mapping>
可以看出union-subclass只需要指定一个表名即可
插入测试结果很简单,就是发出两条inert语句,插入到对应的表中即可
Hibernate: select max(ids_.pid) from ( select pid from union_person union select pid from union_worker ) ids_ Hibernate: insert into union_person (name, age, pid) values (?, ?, ?) Hibernate: insert into union_worker (name, age, job, unit, pid) values (?, ?, ?, ?, ?)
查询结果如下(hql也要使用类全名)
Hibernate: select person0_.pid as pid3_, person0_.name as name3_, person0_.age as age3_, person0_.job as job4_, person0_.unit as unit4_, person0_.clazz_ as clazz_ from ( select pid, name, age, null as job, null as unit, 0 as clazz_ from union_person union select pid, name, age, job, unit, 1 as clazz_ from union_worker ) person0_ Hibernate: select worker0_.pid as pid3_, worker0_.name as name3_, worker0_.age as age3_, worker0_.job as job4_, worker0_.unit as unit4_ from union_worker worker0_ [Person [id=1, name=tom, age=10], Worker [job=washer, unit=bj]] [Worker [job=washer, unit=bj]]
我们着重看一下父类的查询sql,比较有意思,它也将子类查询出来了,它先通过union将两张表联合查询,再从联合查询的结果中获取结果。
最后分析下二者的缺点:
1.插入与查询的效率都低下
2.union-subclass在更新父类表时效率低下
相关文章推荐
- PostgreSQL教程(三):表的继承和分区表详解
- Lua面向对象之类和继承浅析
- 浅析Ruby中继承和消息的相关知识
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++实现不能被继承的类实例分析
- C# 面向对象三大特性:封装、继承、多态
- PHP类的封装与继承详解
- js继承 Base类的源码解析
- Javascript 面向对象 继承
- JavaScript 继承使用分析
- Javascript面向对象编程(二) 构造函数的继承
- Javascript中的几种继承方式对比分析
- javascript面向对象之Javascript 继承
- JavaScript 对象、函数和继承
- 详述JavaScript实现继承的几种方式(推荐)
- javascript 继承学习心得总结
- 学习javascript面向对象 javascript实现继承的方式
- 关于JavaScript的面向对象和继承有利新手学习
- javascript 用函数实现继承详解
- JavaScript 继承详解(一)