Single table inheritance:单表继承
转于:
http://my4java.itpub.net/post/9983/78535
一、介绍:
关系数据库不支持继承,所以在将对象映射到数据库时,我们必须考虑如何在关系表中表现我们完美的继承结构。当映射到一个关系数据库时,我们试图最小化在多个表内处理一个继承体系时快速增长的结合。单表继承则将一个继承体系的所有类映射到单个表的字段中。
在一个关系数据库内至少可以有三种形式来表现继承体系。Martin Fowler 在
http://www.martinfowler.com/eaaCatalog/中做了简短的描述。
1、Class Table Inheritance:继承体系中的每个类都由单个表来表现。
2、Single Table Inheritance:继承体系中的所有类都由一个单独表中的列来表现。
3、Concrete Table Inheritance:继承体系中的每个具体类由单个表来表现。
可参考下面的链接:
1、
http://www.martinfowler.com/eaaCatalog/classTableInheritance.html
2、
http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
3、
http://www.martinfowler.com/eaaCatalog/concreteTableInheritance.html
二、“活动记录”的支持:
“活动记录”使用第二种途径来支持继承,这意味着你必须添加一个string列,通过在列中存储类的名字,而此列缺省地称为,“type”(可以通过覆写Base.inheritance_column来修改缺省名称)。这意味着一个继承看起来是这样的:
class Company < ActiveRecord::Base; end
class Firm < Company; end
class Client < Company; end
class PriorityClient < Client; end
当你完成Firm.create(:name => "37signals"),这个记录将被保存在companies表中且type="firm"。然后你可以使用Company.find(:first, "name = ‘37signals’")来获取此行,并且它会返回一个Firm对象。
如果你没有在你的表内定义type列,则不会触发单表继承。这种情况下,它只是像普通子类一样工作没什么魔术可用。
注意,所有的属性必须位于同一表内。
注意:Rails在使用STI类之前必须能看到包含它们的文件,否则你会得到“uninitialized constant”错误。如果类的名字与包含它的文件的名称不是同样的话,你可能要有麻烦。如果你在'employees.rb'文件内有个“模型”为Manager。在这种情况下,Rails将不能从类名字中分析出文件名。
解决这个问题最简单的方式是添加“model :employees”到你的application.rb“控制器”中,那里'employees'是不带扩展名的,包含STI类的文件名(所以解决上面问题,“模型”应该包含文件名'employees.rb‘才可以。)这会强迫Rails加载此文件并看到你在其内定义的所有“模型”,然后在你使用时,Rails已经知道了你的STI类。
使用Employee[:type]来访问子表信息,不要使用Employee.type。type是一个Ruby废弃的方法,所以直接访问它来设置或修改行的type会导致陌生的Ruby消息。
在使用“单个表继承时“有个明显的约束。两个子类不能有同样名字但不同type的属性,那样两个属性将被映射为同一个列。
三、例子:
# simplified
def new
case @params[:person_type]
when "Manager"
@person = Manager.new
when "Slave"
@person = Slave.new
end
end
在你的“视图”中,完成:
<%= hidden_field_tag "person_type", @person[:type] %>
然后是create方法:
#again, simplified
def create
case @params[:person_type]
when "Manager"
@person = Manager.new(@params[:person])
when "Slave"
@person = Slave.new(@params[:person])
end
if @person.save
redirect_to :action => :list
else
render_action :new
end
end
甚至你可以在你的Person类中创建一个factory类方法。
class Person < ActiveRecord::Base
def self.factory(type, params = nil)
case type
when "Manager"
return Manager.new(params)
when "Slave"
return Slave.new(params)
else
return nil
end
end
end
然后,你可以在new和create方法内完成
def new
@person = Person.factory(@params[:person_type])
end
def create
@person = Person.factory(@params[:person_type], @params[:person])
if @person.save
...
end
end
你也可以使用下面方式来创建一个子类(thanks to Sean Hussey/Ezra)
person_type = "Manager"
@person = eval(person_type + ".new")
或者使用 constantize:
person_type = "Manager"
@person = person_type.constantize.new
如果你的“type”列的文本没有精确地匹配你的类名字,你可能得这样做:
class ETH < ListData; end
Ethnicity = ETH
分享到:
相关推荐
单表继承 单表继承是Laravel 5.8+口才模型的特征,它允许将多个模型存储在同一数据库表中。 我们支持一些关键功能实现为Trait,以便与其他语言(例如Laravel的SoftDeletingTrait或出色的,不需要复杂的...
Laravel-Single-Table-Inheritance 是一个包,它提供了一个简单而基本的模型来使用 eloquent ORM 处理单表继承。 请注意,此模式来自 Martin Fowler(企业应用程序架构模式)。 有关更多信息,请访问此链接:。 另...
在Hibernate 3.2中,类继承有多种策略,包括单表继承(Single Table Inheritance)、联合继承(Joined Table Inheritance)和Concrete Table Inheritance。这些策略各有优缺点,适用于不同的场景。 1. 单表继承...
在Laravel框架中,单表继承(Single Table Inheritance,STI)是一种设计模式,用于处理具有相似属性但类型不同的模型。这种模式允许我们在数据库中只使用一张表来存储多种类型的对象,通过一个额外的字段来区分不同...
在Laravel框架中,Single Table Inheritance(STI,单表继承)是一种设计模式,用于处理具有相似属性但类型略有不同的对象。这种模式允许我们使用单一数据库表来存储多种类型的数据,通过一个字段来区分不同类型的...
Eloquent提供了许多高级特性,其中包括单表继承(Single Table Inheritance,STI)。本教程将深入探讨如何在Laravel项目中利用Eloquent的STI功能。 单表继承是一种设计模式,它允许在同一个数据库表中存储不同类型...
1. **Hibernate的继承策略**:Hibernate支持三种继承策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)和表格-per类继承(Table per Concrete Class)。每种策略都有其适用场景和...
Hibernate提供了四种继承策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)、表 per 类继承(Table per Class Inheritance)以及分层继承(Concrete Table Inheritance)。...
1. **单表继承(Single Table Inheritance,STI)**:在STI中,所有类的实例都存储在一个表中。每个子类在数据库表中增加一个表示类类型的字段,例如`discriminator_column`。当查询时,Hibernate根据这个字段值决定...
因此,Hibernate提供了多种策略来处理这种差异,包括单表继承(Single Table Inheritance)、联合继承(Joined Table Inheritance)和表格分层继承(Table per Class Hierarchy)。 1. 单表继承(Single Table ...
Hibernate提供了四种继承策略:单表继承、联合继承、表-per-hierarchy和表-per-class。 二、单表继承(Single Table Inheritance) 单表继承是最简单的一种策略,所有继承类的数据都存储在同一个表中。通过一个...
Hibernate支持多种继承策略,包括单一表继承(Single Table Inheritance)、联合表继承( Joined Table Inheritance)和表-per类继承(Table per Class Inheritance)。每种策略都有其特定的适用场景和优缺点,下面...
Hibernate支持四种继承映射策略:单表继承(Single Table Inheritance)、联合继承( Joined Subclass)、表 per 类继承(Table per Class Inheritance)和子类表(Concrete Table Inheritance)。在实际应用中,最...
在Hibernate中,继承映射主要有三种策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)和表格-per-类继承(Table per Concrete Class)。本教程可能主要关注的是单表继承,这也是...
本资料将重点介绍Hibernate中的三种继承策略:单表继承、联合继承和表分片继承,并结合源码进行深入解析。 **详细知识点**: 1. **Hibernate ORM**: Hibernate 是一个开源的ORM框架,它允许开发者用面向对象的方式...
1. **单表继承(Single Table Inheritance)**:所有的子类信息存储在同一个表中,通过一个特定的字段来区分不同的子类。 2. **类表继承(Class Table Inheritance)**:每个子类对应一个单独的表,父类的信息则被...
2. **查询效率**:单表继承的查询效率通常较高,因为所有数据都在同一表内。 3. **数据一致性**:联合继承可能导致数据冗余,需要额外维护数据一致性。 4. **扩展性**:如果未来可能会增加新的子类,表-per-class和...