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

一对多关系

阅读更多
一对多关系允许你描述一个对象集合。例如,一个定单可能有多个关联的商品项目。在
数据库中,对于一特定定单的所有商品项目行包含一个外键列来引用这个定单。
在Active Record中,父对象(逻辑上是包含子对象的一个集合)使用has_many来声明对
子表的关系,子表用belongs_to来表明它的父类。在我们的例子中,
类LineItem belongs_to:order和orders表has_many :line_items。
我们已经在前面说了belongs_to()关系声明。它和在一对一关系的处理上是一样的。只
是has_many声明添加了一些功能给它的model。

has_many() 声明
has_many定义了一个属性,它的行为就像子对象集合一样。你可以把子对象当做一个数
据来访问,查找特定的子对象,并可添加新子对象。例如,下面代码添加一些商品项目给一
个定单。
order = Order.new
params[:products_to_buy].each do |prd_id, qty|
product = Product.find(prd_id)
order.line_items << LineItem.new(:product => product,:quantity =>
qty)
end

附加操作符(<<)不仅仅是把一个对象附加到order列表中去。它还通过设置它们的外键
给这个定单的id 来将商品项目连接回到这个定单中,并且当父类定单被保存时,商品项目
也会自动保存。
我们可以迭代具有has_many关系的子类--属性的行为像个数组。
order = Order.find(123)
total = 0.0
order.line_items.each do |li|
total += li.quantity * li.unit_price
end

和has_one一样,你也可以提供给has_many一组哈希表选项来改变Active Record的默
认行为。选项:class_name,:foreign_key,:conditions,:class_name,

:order和:dependent
工作与在has_one内是一样的。
has_many还有:exclusively_dependent,:finder_sql,和:counter_sql。我们也讨论:order选项,我们只是列出它,但是在has_one中讨论它。

has_one和has_many都支持:dependent选项。当你要销毁父表中的一个记录行
时,:dependent就会告诉Rails销毁子表中的记录行。它通过遍历子表,在带有外键信息的
每一个记录行上调用destroy(),并删除父表中的记录。

然而,如果子表只是被父表用到(也就是说,没有其他的依赖关系),并且它没有完成任
何删除操作这样的钩子方法,你可以使用:exclusively_dependent来代替:dependent选项。
如果这个选项被设置了,子表的记录行就要在一个SQL语句中来执行删除。
最后,你可以覆写Active Record用来获取和计数子
表记录行的SQL,这要通过设置:finder_sql,:counter_sql两个选项来做到。在我们碰到where子句中使用:condition不够用时,这两个选项是用的上了。例如,你可以为一个特定产品创建所有商品项目的一个集合。
class Order < ActiveRecord::Base
has_many :rails_line_items,
:class_name => "LineItem",
:finder_sql => "select l.* from line_items l, products p " +
" where l.product_id = p.id " +
" and p.title like '%rails%'"
end

:counter_sql选项被用来覆盖Active Record中用来计数的查询语句。如果:finder_sql
被指定而且:counter_sql没有被指定,Activer Record是使用select count(*)来替换
finder SQL语句中的select部分,来合成counter的sql语句。

: order选项是指定一个SQL片断,它将为从数据库中加载的行定义一个次序后加入到
集合中。如果你需要一种特殊顺序来遍历集合,你就要指定: order选项。你给出的SQL片
断是简单的文本,它将出现在一个select语句的order by子句之后。它是由包含了一个或
多个列名字组成的列表。这个集合将按列表中的第一个列排序。如果两个记录行有相同的列
值,决定它们次序的是列表中的第二个列名,以此类推。默认的排序是升序,可以使用DESC
来降序排序。

下面代码可以被用于指定一个次序的商品项目,它以数量次序被排序(最小的数量在前
面)。
class Order < ActiveRecord::Base
has_many :line_items,
:order => "quantity, unit_price DESC"
end
如果两个商品项目有同样的数量,那么单价最高的被放到前面。
回过头想想,我们讨论过的has_one是,我们也提到它也支持一个: order选项。它看
起来有点奇怪-如果一个父类只和一个子类关联,那当获取那个子类时,指定的是哪个order
呢?
Active Record 可以不在现在的基础数据库上创建has_one关系。例如,一个customer
可能有很多orders:这是一个has_many关系。但是customer将只有一个最近的order。我
们可以使用has_one和: order的结合来表示这个关系:
class Customer < ActiveRecord::Base
has_manyrders
has_one :most_recent_order,
:class_name => 'Order',
:order => 'created_at DESC'
end
这段代码在customer的model中创建一个新的属性,most_recent_order。它将指向最
近created_at时间戳的order。我们可以用这个属性来查找customer的最近order。
cust = Customer.find_by_name("Dave Thomas")
puts "Dave last ordered on #{cust.most_recent_order.created_at}"

这里的代码能起作用,是因为Active Record实际上是使用这样的SQL语句来获取有
has_one关联的数据。
SELECT * FROM orders
WHERE customer_id = ?
ORDER BY created_at DESC
LIMIT 1
limit子句意思是只返回一个记录行,以符合has_one声明。order by子句确保记录行
是最近的记录。
由 has_many() 添加的更多方法
就像belongs_to和has_one一样,has_many给它的主类添加了许多属性方法。同样,
这些方法的名字以属性的名字开头。在下面描述中,我们将列出通过声明来添加的方法。
class Customer < ActiveRecord::Base
has_manyrders
end
1、orders(force_reload=false) 返回一个与这个customer关联的次序的数组(如果没
有的话,它可能为空)。结果被缓存,并且如果次序先前已被获取过,则数据库将不会再次查
询。除非传递true做为一参数。
2、orders <<order 添加次序给与这个customer关联的次序列表。
3、orders.push(order1, ...) 添加一个或多个order对象给与这个customer关联的
order列表。concat()是这个方法的一个别名。
4、orders.delete(order1, ...) 从与这个customer关联的order列表中删除一个或多
个order。这并不会删除数据库内的order对象—它简单地设置它们的customer_id外键为
空,中止它们的关联。
5、orders.clear 从这个customer分离所有order。像delete(),这会中止关联,但从
数据库中删除order,如果它们被标记成:dependent。
6、orders.find(options...) Issues a regular find( ) call, but the results are
constrained only to return orders associated with this customer. Works with the
id, the :all, and the :first forms.
7、orders.build(attributes={}) 构造一个新的order对象,使用给定属性初始化,并
连接给customer。它不会被保存。
8、orders.create(attributes={}) 构造并保存一个新的order对象,使用给定属性来
初始化,并连接给customer。
分享到:
评论

相关推荐

    EF6多对多,一对多关系映射样例代码

    在本示例中,我们将深入探讨如何在EF6中配置和使用多对多和一对多关系,特别是针对Oracle数据库的配置。 首先,多对多关系是指两个实体类型之间存在多个连接,每个实体都可以关联到多个实例。例如,一个学生可以...

    ibatis 一对多关系映射

    一对多关系在数据库设计中非常常见,它意味着一个实体可以与多个其他实体关联。例如,一个用户可能有多个订单,或者一个部门包含多个员工。在Ibatis中,这种关系可以通过配置XML映射文件或使用注解来实现。 首先,...

    java学习--多对多,一对多关系(学校与学生,学生与课程)

    在数据库设计中,一对多关系通常用外键实现,而多对多关系则需要一个联合主键的中间表。在Java中,这些对应于实体类的属性和集合,以及ORM框架中的映射配置。 此外,理解这些关系对于设计高效的数据结构和数据库...

    ext 小示例 实现一对多关系

    这个"ext 小示例 实现一对多关系"是一个使用EXTJS展示数据集合,并处理一对多关系的实例。在EXTJS中,一对多关系通常通过树形结构或者表格的嵌套来实现。 首先,我们来看看`ext.html`文件。这个文件是整个应用的...

    博客(GreenDao一对多关系操作)的示例demo

    **博客GreenDao一对多关系操作示例Demo** 在Android应用开发中,数据库管理是一个不可或缺的部分。GreenDao是一款高效、轻量级的对象关系映射(ORM)框架,它使得Java对象和SQLite数据库之间的交互变得简单。本示例...

    hibernate一对多关系

    在这个"hibernate一对多关系"的资源中,我们主要探讨的是Hibernate如何处理一个实体类与多个实体类之间的关联关系。 在数据库设计中,一对多关系是非常常见的一种关系类型,比如一个部门可以有多个员工,一个学生...

    hibernate anotation 处理一对多关系

    在处理一对多关系时,Hibernate Annotation提供了便捷的方式来表达实体之间的关联。本文将以一个实例为依托,深入解析如何使用注解来设置一对多关系以及多对一关系的映射。 在Hibernate中,处理一对多关系主要使用`...

    退款信息管理系统表的一对多关系.net

    在退款信息管理系统中,"一对多关系"是一个关键的数据库设计概念,用于处理实体间的关系。在这个特定的项目中,标题和描述暗示了系统中可能存在多个退款信息与单个客户或者订单关联,这就是典型的一对多关系。让我们...

    能实现一对多关联的通用EXCEL导入功能

    3. **关联处理**:创建数据模型,体现一对多关系。例如,可以使用外键将学生表格连接到班级表格。在Python中,这可以通过SQLAlchemy等ORM框架实现。 4. **数据导入**:通过批处理或者事务处理,将数据插入到数据库...

    Django 一对多关系

    Django 一对多关系

    Hibernate一对多关系的处理.doc

    在本文中,我们将深入探讨Hibernate框架中的一对多关系处理,这是对象关系映射(ORM)的一个关键概念。Hibernate作为Java领域内的一个流行ORM工具,它允许开发者将数据库操作转化为对象模型的操作,简化了数据库应用...

    《一头扎进MyBatis3》第五讲 一对多关系的实现

    在数据库中,如果一个表(如班级表)的一条记录对应另一个表(如学生表)的多条记录,那么我们就说存在一对多关系。例如,班级表有一个班级ID,而学生表中有对应的班级ID,这样就建立了两个表之间的关联。 在...

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

    **概念**:一对多关系表示一个实体可以与多个其他实体相关联,比如一个用户可以有多个订单。在数据库中,这通常通过在多方实体的表中添加外键实现。 **配置方式**: - 在一方实体上使用`@OneToMany`注解,表示一个...

    ibatis 一对多关系_longjia_zt_新浪博客.mht

    ibatis 一对多关系_longjia_zt_新浪博客.mht

    gorm关联一对多关系golang

    user_topic表里的id,关联...//是这样子的一对多关系 1.model字段部分(加外键关联外键) type UserTopic struct { ID int64 `gorm:"primary_key" json:"id"` UserID int64 `json:"user_id"` TopicImgURL string

    8 映射-- 一对多(部门对员工)

    - 一对多关系是实体之间的一种关联,表示一个实体(如部门)可以与多个其他实体(如员工)相关联。在数据库中,这通常通过在多方(员工)的表中添加一个外键字段来实现,该字段引用一方(部门)的主键。 2. **映射...

    关于关系型数据库基本知识(主键、外键、一对一、一对多、多对一等).docx

    一对多关系是常见的设计模式,一个表的记录对应另一个表的多条记录。例如,一个部门可以有多名员工,部门表和员工表之间就形成了一对多的关系。多对一关系是从一对多的另一个角度看,如员工表中的部门ID可以是部门表...

    SSH一对多(两表双向关联查询)

    通常情况下,一个人可能属于一个或多个组织,而一个组织也可以包含多个人员,这就构成了数据库设计中的一对多关系。在Hibernate中,我们可以使用`@ManyToOne`和`@OneToMany`注解来定义这种关联。 在`person`实体类...

    Laravel5.1 框架模型远层一对多关系实例分析

    在Laravel5.1框架中,模型远层一对多关系是指通过两个中间模型关联起的两个非直接关联的模型间的关系。在这个实例中,我们有三个模型:`Country`(国家)、`User`(用户)和`Article`(文章)。每篇文章都有一个作者...

Global site tag (gtag.js) - Google Analytics