【Hibernate学习】 ——ORM(三)
前面几种关系我们以前就经常用,对于继承我们也并不陌生,经常接触的类与类之间的继承用extends关键字,那么在表与表的关系中如何表示呢?下面我们来讲继承映射。
继承有三种实现的策略,单表继承,具体表继承,类表继承。下面来分析一下这三种方式
继承关联类关系
单表继承
每棵类继承树使用一个表,可知,这三个类在一张表中。如下表:
这张表包括了父类,子类的所有属性,通过Type来区分是哪个子类。
对象模型映射到关系模型:
<classname="com.bjpowernode.hibernat.Animal" table="t_animal"> <idname="id"> <generatorclass="native"/> </id> <!--鉴别字段,父类中定义,指定区分的字段名称和类型--> <discriminatorcolumn="type" type="string"/> <propertyname="name"/> <propertyname="sex"/> <!--鉴别值--> <subclassname="Pig" discriminator-value="P"> <propertyname="weight"/> </subclass> <subclassname="Bird" discriminator-value="B"> <propertyname="height"/> </subclass> </class>
每棵类继承树一张表,类继承树对应多个类,要把多个类的信息放到一张表中,必须有某种机制来区分哪些记录是属于哪个类的。也就是上面discriminator字段,用这个字段的值来区分。
优缺点:表中引入了用来区分子类的字段;如果某个子类的属性不能为空,那么在数据库中不能设置该字段非空,灵活性差;维护方便,只需要修改一张表;如果子类增加,那么表中的冗余字段也会随着增多。如果数据不是很多的话,效率是最好的。
具体表继承
每个子类一个表,与父类所对应的表以一对一主键关联的方式关联起来,如下
animal表中存储了子类的所有记录,只记录公共信息。它们独有的信息存储在子类表中。通过父表与子表的id来进行关联。
对象模型映射到关系模型
<classname="com.bjpowernode.hibernat.Animal" table="t_animal"> <idname="id"> <generatorclass="native"/> </id> <propertyname="name"/> <propertyname="sex"/> <joined-subclassname="Pig" table="t_pig"> <keycolumn="pid"/> <propertyname="weight"/> </joined-subclass> <joined-subclassname="Bird" table="t_bird"> <keycolumn="bird"/> <propertyname="height"/> </joined-subclass> </class>
该类继承映射用<joined-subclass>标签,用于指示父类与子类的关联字段。
优缺点:这种方式符合关系模型的设计原则,不存在冗余,维护起来较方便,对每个类的修改只需要修改其对应的表,灵活性好;完全参照对象继承的方式进行配置。另外层次清晰,但是如果类继承的层次特别多,表特别多时,效率会很低,所以如果层次少的可以用此方式。
类表继承
每个具体类一个表,根据上面的类图看,共有两张表,pig,bird各一张
每个子类对应的数据库表不仅包括自身的属性还包括父类的属性。
对象模型映射到关系模型
<classname="com.bjpowernode.hibernat.Animal" table="t_animal"> <idname="id"> <generatorclass="native"/> </id> <propertyname="name"/> <propertyname="sex"/> <union-subclassname="Pig" table="t_pig"> <keycolumn="pid"/> <propertyname="weight"/> </union-subclass> <union-subclassname="Bird" table="t_bird"> <keycolumn="bird"/> <propertyname="height"/> </union-subclass> </class>
该类型的继承映射用<union-subclass>标签,用于指示出该hbm文件所表示的类的子类
优缺点:该方式符合关系模型的设计原则,但是表中存在重复字段,如果对公共属性部分进行修改则需要修改所有子类所对应表中的属性值,映射的灵活性很大。另外对于子类的查询只需要访问单独的表,对于父类的查询需要检索所有的表。
小结
通过上面三种方式优缺点的总结,再总结一下:
从复杂度的角度,方式1简单(子类属性不多);方式2主外键;方式3有重复字段;
从查询性能,方式1效率高;方式2需要表内连接或左外连接;方式3若查询父类需要查询所有类表;
从可维护性,方式1只需要修改一张表;方式2若某个属性发生变化修改此类对应的表;方式3若父类属性变化需要修改所有子类对应的表。
也就是说,当子类属性不多时,优先选择方式1,;子类属性多,要求不严格时,优先选择方式2。
看完后后,继承映射是不是没有那么深奥了。三种方式听起来很厉害,其实还是围绕着我们之前所学过的主外键,第三张表,各种连接等。这些都是基础。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。