HIbernate继承映射策略
2016-06-10 13:12
375 查看
策略选择:
1)不需要多态关联以及从父类查询时,使用@MappedSuperclass/TABLE_PER_CLASS,偏向于TABLE_PER_CLASS,因为万一有少量需要关联、查询可以在牺牲性能的前提下满足(使用union)。
2)当需要多态以及从父类查询(较多),而且子类较父类的属性变化不大(新增实例域少),可以考虑使用SINGLE_TABLE。
3)当需要多态以及从父类查询(较多),而且子类较父类的属性变化较大(新增实例域多),此时若使用SINGLE_TABLE则造成较多的数据不完整(null)以及范式违反,所以使用TABLE_PER_CLASS/JOINED,具体选择决定于子类的数量(子类多则连接的性能降低),比较性能。
每个具体子类一张表,各有各的id。即直接继承父类的属性到子类中
//以下三种策略,id都必须在父类中定义,最好为protected。
* 每个具体子类一张表,共享主键,select * from Father时,则执行一个union子查询,支持动态绑定以及多态关联,缺点是执行子查询时需要加载所有的子表所以性能较差(如果使用下一个可以直接使用索引快速查找)。
所有的类使用一张表,共享主键,支持多态以及关联,由于一般情况下的最佳选择,但违反第三范式以及数据不够完整(很多null),由于不需要union操作,可以充分利用索引,其性能上优于方式二,性能比较见文末截图。
每个子类一张表,使用连接查询,每个子类使用到父类的外键关联作为主键关联,支持多态与关联,简单但效率较三低。
一个嵌入式类不能使用多态以及关联,所以只有@MappedSuperClass这一策略
多态与代理。
1)不需要多态关联以及从父类查询时,使用@MappedSuperclass/TABLE_PER_CLASS,偏向于TABLE_PER_CLASS,因为万一有少量需要关联、查询可以在牺牲性能的前提下满足(使用union)。
2)当需要多态以及从父类查询(较多),而且子类较父类的属性变化不大(新增实例域少),可以考虑使用SINGLE_TABLE。
3)当需要多态以及从父类查询(较多),而且子类较父类的属性变化较大(新增实例域多),此时若使用SINGLE_TABLE则造成较多的数据不完整(null)以及范式违反,所以使用TABLE_PER_CLASS/JOINED,具体选择决定于子类的数量(子类多则连接的性能降低),比较性能。
每个具体子类一张表,各有各的id。即直接继承父类的属性到子类中
//在父类中使用@MappedSuperclass,每个子类有自己的id(可以继承父类的生成策略与主键名) //缺点是不存在多态关联(id冲突导致),但是只用于拓展父类属性时很实用,一般用于高层次的类(高层类一般不需要多态关联) @MappedSuperclass public abstract class Father{ private String familyName; } @Entity @Table(name="son1") //重写父类属性 @AttributeOverrides() public class Son1 extends Father{ @Id @GeneratedValue private long id; ... } ... write Son2 ...
//以下三种策略,id都必须在父类中定义,最好为protected。
* 每个具体子类一张表,共享主键,select * from Father时,则执行一个union子查询,支持动态绑定以及多态关联,缺点是执行子查询时需要加载所有的子表所以性能较差(如果使用下一个可以直接使用索引快速查找)。
//在父类中使用@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS),在子类中不再配置id,只注解@Entity即可,使得Other -> Father 的关联成为可能 @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Father{ @Id @GeneratedValue protected long id; private String familyName; } //仍旧需要@Entity @Entity public class Son1 extends Father1{ } //union子查询示例 select father0_.id as id1_0_0_, father0_.s1 as s1_1_0_, father0_.s2 as s1_2_0_, father0_.clazz_ as clazz_0_ from ( select id, s1, null as s2, 1 as clazz_ from Son1 union select id, null as s1, s2, 2 as clazz_ from Son2 ) father0_ where father0_.id=?
所有的类使用一张表,共享主键,支持多态以及关联,由于一般情况下的最佳选择,但违反第三范式以及数据不够完整(很多null),由于不需要union操作,可以充分利用索引,其性能上优于方式二,性能比较见文末截图。
//父类使用@Inheritance(strategy = InheritanceType.SINGLE_TABLE),并用@DiscriminatorColumn(name = "BD_TYPE") @Entity指定区别不同子类的列名 @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "BD_TYPE") public abstract class Father{ @Id @GeneratedValue protected long id; private String familyName; } //子类使用 @Entity //指定具体的子类列值,用于多态转换提取数据 @DiscriminatorValue("Son1") public class Son1 extends Father{ ... }
每个子类一张表,使用连接查询,每个子类使用到父类的外键关联作为主键关联,支持多态与关联,简单但效率较三低。
//父类中使用@Inheritance(strategy = InheritanceType.JOINED) @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Father { @Id @GeneratedValue protected long id; ... } //在子类中可以指定引用自父类的外键名(也是该子类的主键) @@Entity @PrimaryKeyJoinColumn(name = "CREDITCARD_ID") public class Son1 extends Father { ... } //实际执行 selct * from Father的过程使用join实现,具体如下 select father0_.id as id1_0_0_, father0_1_.s1 as s1_1_0_, father0_2_.s2 as s1_2_0_, case when father0_1_.id is not null then 1 when father0_2_.id is not null then 2 when father0_.id is not null then 0 end as clazz_0_ from Father father0_ left outer join Son1 father0_1_ on father0_.id=father0_1_.id left outer join Son2 father0_2_ on father0_.id=father0_2_.id where father0_.id=?
一个嵌入式类不能使用多态以及关联,所以只有@MappedSuperClass这一策略
多态与代理。
//使用get(X.class,yy),总是直接命中数据库,返回准确的实现对象 //使用load(X.class,yy),则总是尝试返回X.class的一个代理,所以尝试对load返回的对象进行子类型强转(具体映射到数据库的类型)会出现错误。 //当Fetch配置为lazy时,总是尝试返回代理,与load同理。 //当尝试获取代理的具体方法是会具体命中数据库,底层调用具体类型来实现。
相关文章推荐
- Hibernate Oracle sequence的使用技巧
- jsp Hibernate批量更新和批量删除处理代码
- jsp hibernate的分页代码第1/3页
- Struts2+Hibernate实现数据分页的方法
- Hibernate环境搭建与配置方法(Hello world配置文件版)
- JAVA+Hibernate 无限级分类
- SSH整合中 hibernate托管给Spring得到SessionFactory
- jsp hibernate 数据保存操作的原理
- hibernate中的增删改查实现代码
- 解决hibernate+mysql写入数据库乱码
- java优化hibernate性能的几点建议
- java Hibernate延迟加载
- hibernate 常用方法介绍
- 详解Java的Hibernate框架中的注解与缓存
- 浅析Java的Hibernate框架中的继承关系设计
- Hibernate实现批量添加数据的方法
- Hibernate4在MySQL5.1以上版本创建表出错 type=InnDB
- JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
- SSH框架网上商城项目第16战之Hibernate二级缓存处理首页热门显示
- 深入理解Hibernate中的flush机制