论坛首页 Java企业应用论坛

使用 Subclass 有什麽好处,优点么?

浏览 10519 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-09-22  
我看了一片文章:

引用

2,talbe per class hierarchy
把全部的类层次映射到一张talbe中去。这个table将含有该类层次中所有类的属性所对应的列(column),具体的子类用特殊的一行(row)来表示,这一行由type discriminator来标识。
这种策略既简单性能方面也有不错的表现,对于多态或者非多态查询都适用。
缺点:要求由子类定义的属性必须是可以为null的。否则对于数据完整性而言,会带来严重的问题。
Hibernate中用<subclass>来实现

说的是使用 subclass的优点和缺点,我做了个试验,发现如果定义了子类,那麽如果我用这样的语句
 from parent
,发现他会把所有的 子类和父类统统查询出来! 这样就有什麽好处? 文章上说这样可以给查询带来方便,但是看不出来方便在哪里?!而且这里的子类和父类也不是通常所说的,因为他们没有关联,所以不能体现出关系。 谁用过 subclass能讲讲他的好处么? 多谢!
   发表时间:2004-09-22  
lyo 写道
我看了一片文章:

引用

2,talbe per class hierarchy
把全部的类层次映射到一张talbe中去。这个table将含有该类层次中所有类的属性所对应的列(column),具体的子类用特殊的一行(row)来表示,这一行由type discriminator来标识。
这种策略既简单性能方面也有不错的表现,对于多态或者非多态查询都适用。
缺点:要求由子类定义的属性必须是可以为null的。否则对于数据完整性而言,会带来严重的问题。
Hibernate中用<subclass>来实现

说的是使用 subclass的优点和缺点,我做了个试验,发现如果定义了子类,那麽如果我用这样的语句
 from parent
,发现他会把所有的 子类和父类统统查询出来! 这样就有什麽好处? 文章上说这样可以给查询带来方便,但是看不出来方便在哪里?!而且这里的子类和父类也不是通常所说的,因为他们没有关联,所以不能体现出关系。 谁用过 subclass能讲讲他的好处么? 多谢!


使用这种策略的最好的场景是子类的属性没有什么大多的扩展,而是行为上,说通俗点就是存储在数据库里的数据父类有N个属性,最好子类也有N个同样的属性,它们所不同的就是行为,也就是方法的实现上。

当然子类有自己独自的少量的属性时,也可以采用这种策略,但是必须可以为null,因为此时父类或者其他子类由于没有子类新加的那些属性,相应的值肯定是为null了。

在这张表中的数据所对应的对象没有什么子类父类的对象的分别,大家都同样对待,每个对象不管你是父类还是哪个子类的对象,都对应表中的某一行,它们的地位是同等的。
0 请登录后投票
   发表时间:2004-09-22  
http://forum.iteye.com/viewtopic.php?t=1464&postdays=0&postorder=asc&start=30

你看一下我在那个帖子里面给出来的class diagram。

这是一个应用场景,该场景中Award是奖品类,奖品分为两种:一种是实物奖品,又分为现金奖品和其他赠品,例如手机什么的,另一类是虚拟奖品,虚拟奖品又分为你在系统中的积分,和你在系统中获得的道具。

这是一个奖品的继承树关系,每个子类都具备父类的所有属性,但是又具备自己单独的属性。
0 请登录后投票
   发表时间:2004-09-22  
robbin 写道
http://forum.iteye.com/viewtopic.php?t=1464&postdays=0&postorder=asc&start=30

你看一下我在那个帖子里面给出来的class diagram。

这是一个应用场景,该场景中Award是奖品类,奖品分为两种:一种是实物奖品,又分为现金奖品和其他赠品,例如手机什么的,另一类是虚拟奖品,虚拟奖品又分为你在系统中的积分,和你在系统中获得的道具。

这是一个奖品的继承树关系,每个子类都具备父类的所有属性,但是又具备自己单独的属性。


有个疑问
 1  create table award ( 
 2     id INTEGER NOT NULL AUTO_INCREMENT, 
 3     subclass CHAR(1); not null, 
 4     type VARCHAR(20); not null, 
 5     map_id INTEGER, 
 6     cell_id INTEGER, 
 7     acquriedTime DATE not null, 
 8     player_id INTEGER, 
 9     amount FLOAT not null, 
 10    points INTEGER not null, 
 11    toolcode VARCHAR(20); not null, 
 12    award_id INTEGER, 
 13    primary key (id); 
 14 ); 
 15  
 16 alter table award add index (player_id);, add constraint FK58E7A5D906ADF39 foreign key (player_id); references play (id); 
 17 alter table award add index (award_id);, add constraint FK58E7A5D9F52FE3D foreign key (award_id); references play (id); 
 18 alter table award add index (cell_id);, add constraint FK58E7A5D2786D518 foreign key (cell_id); references cell (id); 
 19 alter table award add index (map_id);, add constraint FK58E7A5DBF8B7EDE foreign key (map_id); references map (id);


你表中那些子类的私有属性是not null的,那些没有这些属性的其他类的对象该如何处理这些不属于自己的属性值?
比如acquriedTime,假如我另有一个类VirtualPointsAwards的对象(VirtualPointsAwards根本没有acquriedTime这个属性,那么DB中对应的row中aquriedTime的值你怎么处理。
0 请登录后投票
   发表时间:2004-09-23  
robbin 写道
http://forum.iteye.com/viewtopic.php?t=1464&postdays=0&postorder=asc&start=30

你看一下我在那个帖子里面给出来的class diagram。

这是一个应用场景,该场景中Award是奖品类,奖品分为两种:一种是实物奖品,又分为现金奖品和其他赠品,例如手机什么的,另一类是虚拟奖品,虚拟奖品又分为你在系统中的积分,和你在系统中获得的道具。

这是一个奖品的继承树关系,每个子类都具备父类的所有属性,但是又具备自己单独的属性。


多谢回复,那个关系我知道,但是看不出来这种设计有任何突出的好处,他只是减少了数据表的数量,简化了POJO的编写(也就是使javabean更简单,因为子类的javabean只需要更少的属性),但是核心问题是:它能给查询带来什麽好处?我暂时想不出来什麽情况下需要把一个父类和他的所有 subclass查询出来(因为这种父子关系并不是以前我们讲的one-to-many!)。版主能解释一下我这个疑问么?多谢!
0 请登录后投票
   发表时间:2004-09-23  
mochow 写道


使用这种策略的最好的场景是子类的属性没有什么大多的扩展,而是行为上,说通俗点就是存储在数据库里的数据父类有N个属性,最好子类也有N个同样的属性,它们所不同的就是行为,也就是方法的实现上。

当然子类有自己独自的少量的属性时,也可以采用这种策略,但是必须可以为null,因为此时父类或者其他子类由于没有子类新加的那些属性,相应的值肯定是为null了。

在这张表中的数据所对应的对象没有什么子类父类的对象的分别,大家都同样对待,每个对象不管你是父类还是哪个子类的对象,都对应表中的某一行,它们的地位是同等的。


那篇文章就是你写的吧,真巧你也在javaeye。 文章上说的查询带来的方便看不出来,你能具个代码例子看看他的优势么?多谢!
0 请登录后投票
   发表时间:2004-09-23  
lyo 写道
robbin 写道
http://forum.iteye.com/viewtopic.php?t=1464&postdays=0&postorder=asc&start=30

你看一下我在那个帖子里面给出来的class diagram。

这是一个应用场景,该场景中Award是奖品类,奖品分为两种:一种是实物奖品,又分为现金奖品和其他赠品,例如手机什么的,另一类是虚拟奖品,虚拟奖品又分为你在系统中的积分,和你在系统中获得的道具。

这是一个奖品的继承树关系,每个子类都具备父类的所有属性,但是又具备自己单独的属性。


多谢回复,那个关系我知道,但是看不出来这种设计有任何突出的好处,他只是减少了数据表的数量,简化了POJO的编写(也就是使javabean更简单,因为子类的javabean只需要更少的属性),但是核心问题是:它能给查询带来什麽好处?我暂时想不出来什麽情况下需要把一个父类和他的所有 subclass查询出来(因为这种父子关系并不是以前我们讲的one-to-many!)。版主能解释一下我这个疑问么?多谢!


这种设计不是为了数据库查询而准备的,而是为了支持整个继承树的持久化功能而做的。你思考问题的角度要从OO持久化来考虑,而不是数据库的什么操作,如果思路转变不过来,学了半天都是白学。

例如我想统计一下当前这个系统当中还剩下多少奖品,如果奖品低于一个比例,我就要给这个游戏系统增加奖品了。此时你不需要关心子类,只需要统计一下Award有多少个就行了。类似的,如果我想看一下系统中有多少实物奖品被领用了,如果达到一个比例,我就要通知人家来领奖了。此时我只需要统计一下ObjectAward有多少个就行,而不需要分别统计两个子类再累加。
0 请登录后投票
   发表时间:2004-09-23  
mochow 写道
robbin 写道
http://forum.iteye.com/viewtopic.php?t=1464&postdays=0&postorder=asc&start=30

你看一下我在那个帖子里面给出来的class diagram。

这是一个应用场景,该场景中Award是奖品类,奖品分为两种:一种是实物奖品,又分为现金奖品和其他赠品,例如手机什么的,另一类是虚拟奖品,虚拟奖品又分为你在系统中的积分,和你在系统中获得的道具。

这是一个奖品的继承树关系,每个子类都具备父类的所有属性,但是又具备自己单独的属性。


有个疑问
 1  create table award ( 
 2     id INTEGER NOT NULL AUTO_INCREMENT, 
 3     subclass CHAR(1); not null, 
 4     type VARCHAR(20); not null, 
 5     map_id INTEGER, 
 6     cell_id INTEGER, 
 7     acquriedTime DATE not null, 
 8     player_id INTEGER, 
 9     amount FLOAT not null, 
 10    points INTEGER not null, 
 11    toolcode VARCHAR(20); not null, 
 12    award_id INTEGER, 
 13    primary key (id); 
 14 ); 
 15  
 16 alter table award add index (player_id);, add constraint FK58E7A5D906ADF39 foreign key (player_id); references play (id); 
 17 alter table award add index (award_id);, add constraint FK58E7A5D9F52FE3D foreign key (award_id); references play (id); 
 18 alter table award add index (cell_id);, add constraint FK58E7A5D2786D518 foreign key (cell_id); references cell (id); 
 19 alter table award add index (map_id);, add constraint FK58E7A5DBF8B7EDE foreign key (map_id); references map (id);


你表中那些子类的私有属性是not null的,那些没有这些属性的其他类的对象该如何处理这些不属于自己的属性值?
比如acquriedTime,假如我另有一个类VirtualPointsAwards的对象(VirtualPointsAwards根本没有acquriedTime这个属性,那么DB中对应的row中aquriedTime的值你怎么处理。


可以指定一个数据库默认值,让数据库自己去填充。如果没有这个字段的对象,是不会去读这个字段的。
0 请登录后投票
   发表时间:2004-09-23  
lyo 写道
mochow 写道


使用这种策略的最好的场景是子类的属性没有什么大多的扩展,而是行为上,说通俗点就是存储在数据库里的数据父类有N个属性,最好子类也有N个同样的属性,它们所不同的就是行为,也就是方法的实现上。

当然子类有自己独自的少量的属性时,也可以采用这种策略,但是必须可以为null,因为此时父类或者其他子类由于没有子类新加的那些属性,相应的值肯定是为null了。

在这张表中的数据所对应的对象没有什么子类父类的对象的分别,大家都同样对待,每个对象不管你是父类还是哪个子类的对象,都对应表中的某一行,它们的地位是同等的。


那篇文章就是你写的吧,真巧你也在javaeye。 文章上说的查询带来的方便看不出来,你能具个代码例子看看他的优势么?多谢!


那是偶的读书笔记。读Hinbernate in action的笔记。

这套策略是针对如何处理继承关系的数据库持久化而言的,跟查询没有什么关系,关于查询Hibernate有它自己的一套东东。有机会的话,推荐你看hibernate in action这本书。

看了potian的话(楼下),偶发现偶的ORM的学习算是失败了,很多概念都没有搞清楚,还需要继续深入学习。
0 请登录后投票
   发表时间:2004-09-23  
这个叫做多态查询,是ORM最强有力的工具之一

所谓多态查询就是可以在查询时只考虑到某一个类层次,因为我们知道子类和父类是一种is a的关系。例如B'继承B,那么B' is a B。如果我们需要针对所有(或者某些条件下)B类型的实例进行处理的话,那么显然B'类型的所有实例同样也是B类型的实例。

因此通常我们不需要知道查询的结果(我们引用的对象)到底是哪一个具体子类。

这种映射方法多态查询效率最高,不需要连接
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics