`
yushine
  • 浏览: 201406 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Zend Framework的DB处理-表关联(转载)

    博客分类:
  • PHP
 
阅读更多

 

介绍:

在RDBMS中,表之间有着各种关系,有一多对应,多多对应等等。
Zend框架提供了一些方法来方便我们实现这些关系。

 

 

定义关系:

下面是本文用的例子的关系定义:

<?php
class Accounts extends Zend_Db_Table_Abstract
{
    protected $_name            = 'accounts';
    protected $_dependentTables = array('Bugs');
}
class Products extends Zend_Db_Table_Abstract
{
    protected $_name            = 'products';
    protected $_dependentTables = array('BugsProducts');
}
class Bugs extends Zend_Db_Table_Abstract
{
    protected $_name            = 'bugs';
    protected 
$_dependentTables = array('BugsProducts');
    protected 
$_referenceMap    = array(
        'Reporter' => array(
            'columns'           => 'reported_by',
            'refTableClass'     => 'Accounts',
            'refColumns'        => 'account_name'
        ),
        'Engineer' => array(
            'columns'           => 'assigned_to',
            'refTableClass'     => 'Accounts',
            'refColumns'        => 'account_name'
        ),
        'Verifier' => array(
            'columns'           => array('verified_by'),
            'refTableClass'     => 'Accounts',
            'refColumns'        => array('account_name')
        )
    );
}
class BugsProducts extends Zend_Db_Table_Abstract
{
    protected $_name = 'bugs_products';
    protected 
$_referenceMap    = array(
        'Bug' => array(
            'columns'           => array('bug_id'),
            'refTableClass'     => 'Bugs',
            'refColumns'        => array('bug_id')
        ),
        'Product' => array(
            'columns'           => array('product_id'),
            'refTableClass'     => 'Products',
            'refColumns'        => array('product_id')
        )
    );
}

 

我们看到例子中定义了四个类:Accounts,Products,Bugs,BugsProducts。其中Accounts,Products和Bugs是三个实体表,而BugsProducts是关系表。
我们再来分析一下这三个实体,一个Account有多个Bug,他们之间是一对多的关系,而Bug和Product是多对多的关系。
 $_dependentTables是一个与该对象关联的对象名,这里注意,要写对象名而不是关联的数据库名。
$_referenceMap 数组用来定义和其他表的关系,在这里可以设置和那些表有关系,有什么样的关系。第一个设置的是Rule Key,也就是上面例子的'Reporter', 'Engineer'之类的。Rule Key的作用其实就是一个关系的名字,并不需要和其他数据库表名或者其他对象名的名字一样。只是为了标记的,在后面的时候,我们可以看到这个Rule Key的作用。

每一个Rule下面都有如下的一些定义:(没有特殊说明,都以如上'Reporter'关系进行说明)

  • columns=> 设置和别的表关联的字段名,如上的'report_by'就是数据库中表Bugs的report_by字段。这里只有一个字段,也可以设置多个字段。
  • refTableClass=>用于设置与这个表发生关系的表。这里要注意,一定使用目标表的对象的名字而不是表名字,例子中就和'Account'对象发生了关联。
  • refColumns =>设置发生联系的表的字段。可以写多个,如果和多个字段发生联系的话,这里要和columns对应。这个设置其实是可选的,如果为空,关联字段自动被设置成为关联表的主键。上面例子中并没有使用主键作为关联字段,所以手动设置。
  • onDelete=>可选字段,设置当删除是的动作。
  • onUpdate=>可选字段,设置当更新表时的动作。

以上定义关系。

 

 

从关联表中取数据:

如果我们已经得到了一个查询结果,我们可以通过一下语句去取得这个结果相关联的表的查询结果

 

 $row->findDependentRowset($table, [$rule]);

 

 

这个方法一般使用与一多对应的两个实体表中,在多多对应的两个实体表和一个关系表如何从一个实体表取出另一个实体表的数据,我们会在下面叙述。
第一个字段 $table 是指和这个表想相联系的表对应的类名。第二个字段是可选的,是我们刚刚说到的 rule key ,就是这个关系的名字,如果省略,则默认为这个表中的第一个关系。下面是例子:  

 

?php
$accountsTable      = new Accounts();
$accountsRowset     = $accountsTable->find(1234);
$user1234           = $accountsRowset->current();
$bugsReportedByUser = $user1234->findDependentRowset('Bugs');

 

 

例子中,我们先读取了一个编号为1234的用户,然后去查找这个家伙报了什么bug,由于zend默认是第一个关联,所以这里和Account发生关联的第一个就是'Reporter,所以就取出了Reporter的记录。

如果我们想取出其他的记录,比如Engineer,可以按照下面的办法:

 

<?php
$accountsTable      = new Accounts();
$accountsRowset     = $accountsTable->find(1234);
$user1234           = $accountsRowset->current();
$bugsAssignedToUser = $user1234->findDependentRowset('Bugs', 'Engineer');
 

 

除了使用findDependentRowset之外,我们还可以使用叫做“魔术方法”(Magic Method)的机制。之所以这么叫,就是因为好像是在变魔术一样。所以方法findDependentRowset('<TableClass>', '<Rule>')就可以等价于如下:
- $row->find<TableClass>()
- $row->find<TableClass>By<Rule>()

注:这个机制是我们最一开始是在Ruby on Rails里面看到的。这里的<TableClass>和<Rule>一定要使用和相关联的类名以及关联名(Rule Key)完全一样的名字,才可以生效。下面是例子:

 

<?php
$accountsTable    = new Accounts();
$accountsRowset   = $accountsTable->find(1234);
$user1234         = $accountsRowset->current();
// Use the default reference rule
$bugsReportedBy   = $user1234->findBugs();
// Specify the reference rule
$bugsAssignedTo   = $user1234->findBugsByEngineer();

 

 

从父表取得字段:

刚刚我们介绍了一多关系中的从一去多的方法,现在我们反过来,从多取一,其实是从多中的一个取他相对应的那个记录。
类似的我们有这样的语句:

 

$row->findParentRow($table, [$rule]);

 

类似的,$table为类名,而可选参数$rule填入对应的Rule Key。下面是例子:

 

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW'));
$bug1              = $bugsRowset->current();
$reporter          = $bug1->findParentRow('Accounts');

 

 

和上面不太一样的是,上面返回的是一个多个记录的集合,而这次返回的必然是一条记录。下面的例子是设置Rule:

 

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1              = $bugsRowset->current();
$engineer          = $bug1->findParentRow('Accounts', 'Engineer');
 

 

只需要吧Rule填入就好了。相似的,这个方法也有“魔术字段”。findParentRow('<TableClass>', '<Rule>')对应:
- $row->findParent<TableClass>()
- $row->findParent<TableClass>By<Rule>()
例子:

 

 

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1              = $bugsRowset->current();
// Use the default reference rule
$reporter          = $bug1->findParentAccounts();
// Specify the reference rule
$engineer          = $bug1->findParentAccountsByEngineer();

 

 

取得多对多关系表的字段:

上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:

 

$row->findManyToManyRowset($table, $intersectionTable, [$rule1, [$rule2]]);

 

 

这里参数变成了4个,因为需要增加一个关系表来存储多对多的关系。
$table是与之发生多对多关系的表的类名,$intersectionTable是中间存储关系的关系表的类名。$rule1和$rule2是上面两个数据表的Rule Key。省略Rule Key的例子如下:

 

 

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();
$productsRowset   = $bug1234->findManyToManyRowset('Products', 'BugsProducts');

 

下面是该方法的全部参数调用例子:

 

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();
$productsRowset   = $bug1234->findManyToManyRowset('Products', 'BugsProducts', 'Bug');

 

 

这次的“魔术方法”是,对应 findManyToManyRowset('<TableClass>', '<IntersectionTableClass>', '<Rule1>', '<Rule2>')
- $row->find<TableClass>Via<IntersectionTableClass>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>()

例子:

 

 

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();
// Use the default reference rule
$products          = $bug1234->findProductsViaBugsProducts();
// Specify the reference rule
$products          = $bug1234->findProductsViaBugsProductsByBug();

 

 

 

分享到:
评论

相关推荐

    Zend Framework教程之Zend_Db_Table表关联实例详解

    Zend Framework中包含一个重要的组件Zend_Db,它为数据库操作提供了对象关系映射(ORM)的实现,其中Zend_Db_Table是用于表数据访问和管理的主要类。 在数据库中,表之间经常会存在复杂的关系,例如一对多或多对多的...

    Zend Framework 多表关联 数据库操作、事务处理

    在Zend Framework中,ORM组件如 Doctrine 或 Zend\Db 提供了对多表关联的支持,使得开发者可以方便地处理复杂的数据库操作。 “数据库操作”涵盖了一系列与存储和检索数据相关的任务,包括创建、读取、更新和删除...

    zendframework增删改查

    "zendframework增删改查"这个主题主要涵盖了使用ZF进行数据操作的基础知识。 **1. 数据库连接与配置** 在 Zend Framework 中,我们通常使用`Zend_Db`组件来管理数据库连接。首先,需要在`application/configs/...

    ZendFramework中文文档

    1. Introduction to Zend Framework 1.1. 概述 1.2. 安装 2. Zend_Acl 2.1. 简介 2.1.1. 关于资源(Resource) 2.1.2. 关于角色(Role) 2.1.3. 创建访问控制列表(ACL) 2.1.4. 注册角色(Role) 2.1.5. 定义访问...

    Zend framework数据库简单操作

    在 Zend Framework 中,数据库操作主要通过 `Zend_Db` 组件来实现。`Zend_Db` 提供了对多种数据库系统的支持,如 MySQL、PostgreSQL、SQLite 等。开发者可以使用它来执行 SQL 查询,进行数据的读取、插入、更新和...

    ZendFramework入门实例源码

    - 表关系:处理一对多、一对一或多对多的关系,通过JOIN实现关联查询。 **5. 学习资源** 对于初学者,官方文档是很好的学习起点,它详细解释了框架的每个组件。同时,网上有许多教程和社区讨论,如Stack Overflow...

    ZendFramework的数据库处理[借鉴].pdf

    在 Zend Framework (ZF) 中,数据库处理是一个关键部分,它提供了一个强大的DB类库,使得开发者可以方便地进行面向对象的数据库操作。这个类库对数据库层进行了封装,使得基本的SQL操作变得更加简洁和易于理解。在...

    Zend Framework教程之Zend_Db_Table用法详解

    ZendFramework会自动处理数据的安全引用,并返回插入的最后一行的id值。 ```php $data = array( 'noble_title' =&gt; 'King', 'first_name' =&gt; 'Arthur', 'favorite_color' =&gt; 'blue' ); $table-&gt;insert($data); ``...

    cursor-oracle-zend-framework-adapter:这是在 Zend Oracle 适配器中执行游标的小扩展

    而在PHP中,当我们使用Zend Framework进行开发时,如果需要与Oracle数据库交互,通常会使用Zend_Db_Adapter_Pdo_Oci类,它提供了对Oracle数据库的PDO(PHP Data Objects)支持。 `cursor-oracle-zend-framework-...

    zf框架的zend_cache缓存使用方法(zend框架)

    在 Zend Framework 中,`Zend_Cache` 是一个强大的组件,用于处理应用程序的缓存需求。它提供了多种缓存后端(如文件、数据库、memcached 等)以及前端缓存策略,以优化性能并减少对服务器资源的依赖。以下是对 `...

    Zend Framework教程之Zend_Db_Table_Row用法实例分析

    Zend_Db_Table_Row是Zend Framework的一个核心部分,它作为数据表中一行的抽象表示。你不应该直接实例化Zend_Db_Table_Row对象,而是通过调用`Zend_Db_Table::find()`或`Zend_Db_Table::fetchRow()`方法从数据库...

    Zend Framework教程之模型Model用法简单实例

    在Zend Framework中使用模型可以帮助开发者更好地组织代码、提升数据处理能力并增强应用的可维护性。 在本次提供的“Zend Framework教程之模型Model用法简单实例”内容中,我们将探讨Zend Framework中模型的定义、...

    Zend框架和相关配置

    在 Zend Framework 中,视图脚本通常位于 `application/views` 目录下,与控制器动作关联,用于呈现由模型处理后的数据。 3. **Controller(控制器)**:控制器是模型和视图之间的桥梁,处理用户请求,调用模型执行...

    Zend Framework连接Mysql数据库实例分析

    2. **Zend_Db**:Zend Framework中的数据库抽象层,简化了数据库操作。 3. **MVC架构**:Model处理数据,View展示数据,Controller协调Model和View。 4. **注册表(Registry)**:用于存储和检索全局应用对象,避免...

    Zend Framework数据库操作方法实例总结

    Zend Framework 提供了一套完整的数据库访问组件,使得开发者能够轻松地执行各种数据库操作,包括查询、连接管理以及事务处理等。 首先,我们来看一下如何在 Zend Framework 中创建基本的查询。例如,如果你想要...

Global site tag (gtag.js) - Google Analytics