`
jbf034
  • 浏览: 152355 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

一对一关系

阅读更多
一对一关系(或者更正确的是,一对零或一关系)由一个表内的行中的一个外键实现,它
至少引用了另一个表的单个行。上面图显示了order和invoice之间的一对一关系:一个order可以没有invoice引用它或者只有一个invoice引用它。
在Active Record内,我们通过添加声明has_one :invoice给类Order来表示这种关系 ,同时,添加belongs_torder给类Invoice。(记住belongs_to行必须出现在用于包含外键的表的model内。)你可以从关联的任一端用一个order来关联一个invoice。
你可以告诉一个order,它有一个invoice与它关联,或者你可以告诉invoice,它与一
个order关联。这两者是相等的。区别是它们保存对象到数据库的方式。如果你给一个对象
赋值一个has_one关联一个现有对象,那个被关联的对象将被自动地保存。

an_invoice = Invoice.new(...)
order.invoice = an_invoice # invoice gets saved

相反,如果你给一个新对象赋值一个belongs_to 关联,它将不会被自动保存。
order = Order.new(...)
an_invoice.order = order # Order will not be saved

这儿有个区别。如果你给一个新对象赋值has_one关联时,如果这儿已经存在一个子对
象,那个现有对象将被更新来移除与父行关联的外键(外键将被设置为零)。这在图14.4中显
示。
最后,这是危险的。如果子行不能被保存(例如,因它确认失败),Active Record将不
会抱怨—你将得不到暗示,行不能被添加到数据库。对于这个原因,我们强烈推荐代替先前
代码,你写出
invoice = Invoice.new
# fill in the invoice
unless invoice.save!
an_order.invoice = invoice
save!方法在失败时抛出一个异常,所以至少你将知道有些东西出错误了。
belongs_to() 声明belongs_to()声明给定的类是本身类的父类。尽管belongs_to可能不是我们考虑这种关
系时最先想到的词,但是Active Record的约定是包含外键的表属于它引用的表。如果这有
助于编码的话,你应该把references当成belongs_to使用。
我们假定父类的名字是属性名大小写混合的单数形式,外键字段是附加_id的属性名的
单数形式。所以,给出下面代码

class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :invoice_item
end

Active Record把商品项目和类Product,InvoiceItem相关联。(特别注意:其中的单
复数形式的变化。)其中隐含的意思是,它使用了外键product_id,invoice_item_id来引用表products,invoice_items的id列。
还可以覆写这些,其它人会假设传给belongs_to()一个选项的哈希表散列值改变这些
定。

class LineItem < ActiveRecord::Base
belongs_to :paid_order,
:class_name => "Order",
:foreign_key => "order_id",
:conditions => "paid_on is not null"
end

这个例子中,我们创建了一个paid_order的关联,它是类Order的引用(对应的表
orders)。这连接是通过order_id外键建立的,但是它还是有条件限制的,如果目标行的
paid_on列不为null,它将找到一个定单。这个例子中,我们并没有使用对line_items表
的单个列直接映射来建立连接。
belongs_to()方法创建许多管理连接的实例方法。这些方法都是以连接名开头来命名
例如:

item = LineItem.find(2)
# item.product is the associated Product object
puts "Current product is #{item.product.id}"
puts item.product.title
item.product = Product.new(:title => "Advanced Rails",
:description => "...",
:image_url => "http://....jpg",
:price => 34.95,
:date_available => Time.now)
item.save!
puts "New product is #{item.product.id}"
puts item.product.title
如果我们运行它(用一个适当的数据连接),可能会有以下的结果。
Current product is 2
Programming Ruby
New product is 37
Advanced Rails

我们在LIneItem类中使用方法product(),product!=()来存取和更新与product对象
关联的商品项目对象。在背后,Active Record是和数据库的机制是一样的。当我们保存对
应的商品项目时,它自动保存创建的新product。并把新的product的id号和商品项目连接
belongs_to()会把方法添加到使用它的类中。这个描述是基于以下的假定,已定义的
LineItem类属于类Product。
class LineItem < ActiveRecord::Base
belongs_to :product
end

在这个例子中,下面方法将被定义用于商品项目,以及它们属于的products。
1、product(force_reload=false) 返回关联的产品(如果没有关联的产品存在,则返回
nil)。结果被缓存,如果这个定单先前被取出过,则数据库不会再次查询,除非将true做为
一个参数传递给它。

2、product=(obj) 用给出的产品关联这个商品项目,在这个商品项目内设置外键给产品
的主键。如果产品没有被保存,在商品项目被保存时它将被保存,键将在那时被连接。

3、build_product(attributes={}) 构造一个新的product对象,并用给定的属性初始
化它。这个商品项目将被连接给它。Product也不会被保存。

4、create_product(attributes={}) 构建一个新的product对象,连接这个商品项目给
它,然后保存这个product。

has_one() 声明
has_one声明一个给定的类(缺省是混合大小写的属性名字的单数形式)是这个类的子类。
has_one声明和belongs_to一样定义同一个方法集,因此给定类定义例如:
class Order < ActiveRecord::Base
has_one :invoice
end

我们可写成
order = Order.new
invoice = Invoice.new
if invoice.save
order.invoice = invoice
end

你可以通过给has_one传递一个选项的哈希表,来改变Active Record的默认行为。另
外对于:class_name,:foreign_key,和:conditions选项,我们可以看到belongs_to(),我们也可以使用:dependent和: order。

:dependent选项是指子表中的记录行不能独立于对应的父表记录行而单独存在。这就意
味着如果你删除了父类的记录,而且你定义了:dependent=>true的话,Active Record将会自动删除子表中相关的记录行。

: order选项,是决定记录返回之前怎样排序。这似乎有点奇怪。我们在277页的has_many
中还会讨论。
分享到:
评论

相关推荐

    Hibernate一对一关系源码

    在Hibernate中,一对一关系是指两个实体类之间存在一个唯一的对应关系,通常通过主键外键关联实现。下面我们将详细探讨这种关系的配置、实现方式以及源码解析。 1. **配置一对一关系**: - 在实体类中使用`@...

    EJB3一对一关系映射实例

    首先,一对一关系映射意味着两个实体之间存在唯一的关系,即一个实体对应另一个实体的唯一实例。在EJB3中,我们可以使用注解来定义这种关系。例如,如果我们有两个实体类,一个是`Employee`,另一个是`PersonalInfo`...

    Hiberante part 9:一对一关系映射

    一对一关系映射是数据库设计中常见的一种关联类型,表示一个实体与另一个实体之间存在唯一的对应关系。 首先,我们需要理解一对一关系的基本概念。在数据库设计中,一对一关系意味着两个表中每一条记录都唯一地对应...

    Hibernate 一对一关系(基于XML)

    本篇将详细探讨“Hibernate 一对一关系(基于XML)”这一主题,主要关注如何在Hibernate中配置和实现一对一的关系映射。 一对一关系在数据库设计中表示两个表之间存在唯一的对应关系,比如一个员工只有一个身份证,...

    Mybatis课程实验报告及源码,实验名称:Mybatis完成一对一关系映射(可不用修改直接使用)

    “Mybatis课程实验报告及源码-实验名称:Mybatis完成一对一关系映射(可不用修改直接使用).zip” 是一份关于Mybatis框架实验的报告,附带了完整的源代码和示例项目。以下是对这份实验报告的详细描述: 这份实验...

    一对一关系实现.bmp

    一对一关系实现.bmp

    hibernate一对一的关系

    接下来我们将深入探讨Hibernate中的一对一关系映射。 ### 1. 一对一关系的类型 一对一关系分为两种类型:单向和双向。 - **单向一对一**:只有一个实体知道另一个实体的存在,通常通过在一方的类中定义`@OneToOne...

    JPA一对一,一对多,多对多关系映射

    **概念**:一对一关系意味着两个实体之间存在唯一的关联,一个实体实例对应另一个实体的唯一实例。在数据库中,这通常通过外键约束实现。 **配置方式**: - 使用`@OneToOne`注解在实体类的属性上表示一对一关系。 -...

    hibernate 一对一 多对多的关系

    **一对一关系映射** 一对一关系是指两个实体之间存在唯一对应的关系,比如一个人只有一个身份证。在Hibernate中,我们可以通过以下方式实现一对一关系映射: 1. **注解方式**:在两个实体类中,都可以定义`@...

    Hibernate ORM - 一对一外键关联关系

    综上所述,"Hibernate ORM - 一对一外键关联关系"是一个关于如何在Hibernate中设置和管理一对一关系的专题,涉及源码配置、工具使用和性能优化等多个方面。通过阅读相关的博客文章和实践压缩包中的示例,开发者可以...

    Laravel5.1 框架模型一对一关系实现与使用方法实例分析

    一对一关系是最基本的关系类型之一,它指出两个模型(或表)之间存在一对一的对应关系。例如,在一个用户系统中,一个用户对应一个账号,而一个账号只能属于一个用户,这就构成了一个典型的“一对一”关系。 在...

    hibernate一对一关系详解

    博文链接:https://dlivan.iteye.com/blog/54966

    Hibernate关于注解的一对多,多对多,一对一

    本篇文章将深入探讨Hibernate中注解的一对多、多对多和一对一关系映射。 ### 一对多关系 在现实生活中,例如一个班级有一个班主任,而班主任可以管理多个学生,这就是典型的“一对多”关系。在Hibernate中,我们...

    hibernate常用一对一、一对多、多对一、多对多映射关系真实例子(华南银行项目)

    在数据库设计中,一对一关系通常出现在两个表共享主键的情况。在Hibernate中,可以通过`@OneToOne`注解实现。例如,一个用户可能只有一个账户,我们可以定义User和Account类,用`@OneToOne`注解建立它们之间的关联,...

    hibernate 关系注解

    使用`@OneToOne`注解实现一对一关系,其中一方通过外键引用另一方。`@JoinColumn`用于指定外键的名称,`unique=true`确保外键的唯一性。例如: ```java @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name=...

    ibatis的的增删改查和一对一、一对多查询

    1. **一对一关系**:在一个实体类中,可能存在与另一个实体类一对一的关系。在iBatis中,可以通过`resultMap`来配置。例如,用户和用户详细信息是一对一关系: ```xml ``` 在SQL查询中,可以使用...

    oracle 数据库关系映射

    - 一对一关系是最简单的一种关系类型,表示两个实体之间仅有一种关联。可以通过在其中一个实体的表中添加另一个实体的主键作为外键来实现。 - 例如,员工和其个人信息之间的关系,可以将员工个人信息的主键添加到...

    EJB 一对一 一对多 多对多 的代码

    一对一关系是指两个实体类之间存在一对一的关联,即一个实体对应另一个实体的唯一实例。在EJB中,可以通过`@OneToOne`注解来定义这种关系。该注解可以放在属性上,表示这个属性引用的是另一个实体的唯一实例。同时,...

Global site tag (gtag.js) - Google Analytics