一对一关系(或者更正确的是,一对零或一关系)由一个表内的行中的一个外键实现,它
至少引用了另一个表的单个行。上面图显示了order和invoice之间的一对一关系:一个order可以没有invoice引用它或者只有一个invoice引用它。
在Active Record内,我们通过添加声明has_one :invoice给类Order来表示这种关系 ,同时,添加belongs_to
rder给类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
中还会讨论。
分享到:
相关推荐
通过主函数了解Java中一对一关系,如本列中从Person到child、book。实现从book到person在到child,或从person到child再到book
本话题主要关注MyBatis中的一对一关系映射,这是一种常见的数据库关联关系,用于描述一个实体与另一个实体之间的对应关系。 一对一关系映射在数据库设计中意味着一个表中的记录唯一对应另一个表中的记录。例如,...
在Hibernate中,一对一关系是指两个实体类之间存在一个唯一的对应关系,通常通过主键外键关联实现。下面我们将详细探讨这种关系的配置、实现方式以及源码解析。 1. **配置一对一关系**: - 在实体类中使用`@...
一对一关系映射是数据库设计中常见的一种关联类型,表示一个实体与另一个实体之间存在唯一的对应关系。 首先,我们需要理解一对一关系的基本概念。在数据库设计中,一对一关系意味着两个表中每一条记录都唯一地对应...
“Mybatis课程实验报告及源码-实验名称:Mybatis完成一对一关系映射(可不用修改直接使用).zip” 是一份关于Mybatis框架实验的报告,附带了完整的源代码和示例项目。以下是对这份实验报告的详细描述: 这份实验...
在MyBatis框架中,一对一关系的实现是一个重要的概念,特别是在处理复杂的数据库操作时。这一讲我们将深入探讨如何在MyBatis中配置和使用一对一映射,以方便地获取两个关联表的数据。 首先,我们需要理解一对一关系...
一对一关系实现.bmp
一对一关系相对少见,一般出现在将大型表拆分为更小、更专注的表以优化管理的情况。例如,员工表和用户表可以通过一对一关系关联,以满足不同的业务需求。这种设计可以提高查询速度,符合数据库设计规范,但也会增加...
**概念**:一对一关系意味着两个实体之间存在唯一的关联,一个实体实例对应另一个实体的唯一实例。在数据库中,这通常通过外键约束实现。 **配置方式**: - 使用`@OneToOne`注解在实体类的属性上表示一对一关系。 -...
**一对一关系映射** 一对一关系是指两个实体之间存在唯一对应的关系,比如一个人只有一个身份证。在Hibernate中,我们可以通过以下方式实现一对一关系映射: 1. **注解方式**:在两个实体类中,都可以定义`@...
例如,Student实体和IdCard实体可以建立一对一关系: ```java @Entity public class Student { @OneToOne(mappedBy = "student") private IdCard idCard; } @Entity public class IdCard { @OneToOne @...
一对一关系通常发生在两个实体之间,例如一个用户对应一个唯一地址。在MyBatis中,可以通过`<association>`标签来配置一对一的关系。 1. **配置XML映射文件**: 在Mapper XML文件中,定义查询语句,并使用`...
综上所述,"Hibernate ORM - 一对一外键关联关系"是一个关于如何在Hibernate中设置和管理一对一关系的专题,涉及源码配置、工具使用和性能优化等多个方面。通过阅读相关的博客文章和实践压缩包中的示例,开发者可以...
1. **一对一关系映射:** 在数据库设计中,一对一关系是指两个表中每一条记录都唯一对应另一表中的某一条记录。在Hibernate中,这通常通过在一方实体类中添加对另一方实体的引用来实现。 2. **单向关联:** 在一对...
一对一关系是最基本的关系类型之一,它指出两个模型(或表)之间存在一对一的对应关系。例如,在一个用户系统中,一个用户对应一个账号,而一个账号只能属于一个用户,这就构成了一个典型的“一对一”关系。 在...
本篇文章将深入探讨Hibernate中注解的一对多、多对多和一对一关系映射。 ### 一对多关系 在现实生活中,例如一个班级有一个班主任,而班主任可以管理多个学生,这就是典型的“一对多”关系。在Hibernate中,我们...
- **定义**:一对一关系指的是两个表中的记录互相独立,每一条记录在另一表中都有且仅有一个匹配的记录。例如,一个身份证对应一个公民,一个公民对应一个身份证。 - **建表原则**:一对一关系可以通过两种方式...
在数据库设计中,一对一关系通常出现在两个表共享主键的情况。在Hibernate中,可以通过`@OneToOne`注解实现。例如,一个用户可能只有一个账户,我们可以定义User和Account类,用`@OneToOne`注解建立它们之间的关联,...
一对一关系表示两个实体之间存在唯一关联,如一个人只有一个身份证。在Hibernate中,可以使用`@OneToOne`注解。 **配置示例:** 1. 在两个实体类中都添加`@OneToOne`注解,并通过`@PrimaryKeyJoinColumn`或`@MapsId...
使用`@OneToOne`注解实现一对一关系,其中一方通过外键引用另一方。`@JoinColumn`用于指定外键的名称,`unique=true`确保外键的唯一性。例如: ```java @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name=...