一对一关系

一对一关系(或者更正确的是,一对零或一关系)由一个表内的行中的一个外键实现,它
至少引用了另一个表的单个行。上面图显示了order和invoice之间的一对一关系:一个order可以没有invoice引用它或者只有一个invoice引用它。
在Active Record内,我们通过添加声明has_one :invoice给类Order来表示这种关系 ,同时,添加belongs_to :order给类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!方法在失败时抛出一个异常,所以至少你将知道有些东西出错误了。
[color=red]belongs_to() 声明[/color]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。

[color=red]has_one() 声明[/color]
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
中还会讨论。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中的一对一关系映射是通过使用association元素来实现的。在给定的范例中,Person和IdCard之间的一对一关系被映射成了Java对象的关系。具体来说,Person对象中有一个名为idCard的属性,该属性引用了一个IdCard对象。这个映射是通过在PersonMapper.xml文件中的resultMap元素中定义的association元素来完成的。 在association元素中,我们可以指定关联属性的名称、数据库中对应的列名,以及关联属性的类型。此外,我们还可以使用select属性来指定一个额外的SQL语句,以在查询Person对象时一起查询关联的IdCard对象。在给定的例子中,select属性的值为"com.wx.mapper.IdCardMapper.searchIdCard",表示在查询Person对象时,同时查询关联的IdCard对象。 在Java代码中调用一对一关系映射的方法可以使用MyBatis的SqlSession对象的selectOne或selectList方法。在给定的例子中,使用了selectList方法来查询id为1的Person对象,并将结果存储在名为list3的List对象中。然后使用System.out.println打印出查询结果。 总结来说,MyBatis中的一对一关系映射可以通过在resultMap中使用association元素来设置关联属性,并在查询时使用select属性来同时查询关联对象的信息。通过调用SqlSession的selectOne或selectList方法可以执行一对一关系映射的查询操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Mybatis中的一对一关系映射](https://blog.csdn.net/Altitude_/article/details/101206178)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值