`
xu_wccq
  • 浏览: 130874 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Single table inheritance:单表继承

    博客分类:
  • ruby
阅读更多
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
分享到:
评论

相关推荐

    single-table-inheritance:EloquentLaravel的单表继承特性

    单表继承 单表继承是Laravel 5.8+口才模型的特征,它允许将多个模型存储在同一数据库表中。 我们支持一些关键功能实现为Trait,以便与其他语言(例如Laravel的SoftDeletingTrait或出色的,不需要复杂的...

    laravel-single-table-inheritance:一个包含 eloquent(laravel orm) 单表继承模型的包

    Laravel-Single-Table-Inheritance 是一个包,它提供了一个简单而基本的模型来使用 eloquent ORM 处理单表继承。 请注意,此模式来自 Martin Fowler(企业应用程序架构模式)。 有关更多信息,请访问此链接:。 另...

    (2)Hibernate3.2 中的类继承关系

    在Hibernate 3.2中,类继承有多种策略,包括单表继承(Single Table Inheritance)、联合继承(Joined Table Inheritance)和Concrete Table Inheritance。这些策略各有优缺点,适用于不同的场景。 1. 单表继承...

    Laravel开发-single-table-inheritance

    在Laravel框架中,单表继承(Single Table Inheritance,STI)是一种设计模式,用于处理具有相似属性但类型不同的模型。这种模式允许我们在数据库中只使用一张表来存储多种类型的对象,通过一个额外的字段来区分不同...

    Laravel开发-laravel-single-table-inheritance

    在Laravel框架中,Single Table Inheritance(STI,单表继承)是一种设计模式,用于处理具有相似属性但类型略有不同的对象。这种模式允许我们使用单一数据库表来存储多种类型的数据,通过一个字段来区分不同类型的...

    Laravel开发-eloquent-single-table-inheritance

    Eloquent提供了许多高级特性,其中包括单表继承(Single Table Inheritance,STI)。本教程将深入探讨如何在Laravel项目中利用Eloquent的STI功能。 单表继承是一种设计模式,它允许在同一个数据库表中存储不同类型...

    15 继承(二)(每个子类扩展的属性单独保存在一张表中)

    1. **Hibernate的继承策略**:Hibernate支持三种继承策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)和表格-per类继承(Table per Concrete Class)。每种策略都有其适用场景和...

    Hibernate继承映射代码

    Hibernate提供了四种继承策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)、表 per 类继承(Table per Class Inheritance)以及分层继承(Concrete Table Inheritance)。...

    14 继承(一)(整个继承树映射到一张表)

    1. **单表继承(Single Table Inheritance,STI)**:在STI中,所有类的实例都存储在一个表中。每个子类在数据库表中增加一个表示类类型的字段,例如`discriminator_column`。当查询时,Hibernate根据这个字段值决定...

    hb_hibernate_05

    因此,Hibernate提供了多种策略来处理这种差异,包括单表继承(Single Table Inheritance)、联合继承(Joined Table Inheritance)和表格分层继承(Table per Class Hierarchy)。 1. 单表继承(Single Table ...

    hibernate继承映射.rar

    Hibernate提供了四种继承策略:单表继承、联合继承、表-per-hierarchy和表-per-class。 二、单表继承(Single Table Inheritance) 单表继承是最简单的一种策略,所有继承类的数据都存储在同一个表中。通过一个...

    用Hibernate映射继承关系

    Hibernate支持多种继承策略,包括单一表继承(Single Table Inheritance)、联合表继承( Joined Table Inheritance)和表-per类继承(Table per Class Inheritance)。每种策略都有其特定的适用场景和优缺点,下面...

    hibernate 映射继承 demo

    Hibernate支持四种继承映射策略:单表继承(Single Table Inheritance)、联合继承( Joined Subclass)、表 per 类继承(Table per Class Inheritance)和子类表(Concrete Table Inheritance)。在实际应用中,最...

    Hibernate教程17_继承映射

    在Hibernate中,继承映射主要有三种策略:单表继承(Single Table Inheritance)、联合继承( Joined Table Inheritance)和表格-per-类继承(Table per Concrete Class)。本教程可能主要关注的是单表继承,这也是...

    hibernate

    本资料将重点介绍Hibernate中的三种继承策略:单表继承、联合继承和表分片继承,并结合源码进行深入解析。 **详细知识点**: 1. **Hibernate ORM**: Hibernate 是一个开源的ORM框架,它允许开发者用面向对象的方式...

    Hibernate继承映射(annotation)

    1. **单表继承(Single Table Inheritance)**:所有的子类信息存储在同一个表中,通过一个特定的字段来区分不同的子类。 2. **类表继承(Class Table Inheritance)**:每个子类对应一个单独的表,父类的信息则被...

    Hibernate继承映射-概述

    2. **查询效率**:单表继承的查询效率通常较高,因为所有数据都在同一表内。 3. **数据一致性**:联合继承可能导致数据冗余,需要额外维护数据一致性。 4. **扩展性**:如果未来可能会增加新的子类,表-per-class和...

Global site tag (gtag.js) - Google Analytics