其它综合

Zend_Db_Table 表关联

我爱IT资讯库   2021/02/20

 

介绍:

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

定义关系:

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

 <php
class Accounts extends Zend_Db_Table_Abstract
{
    protected 
$_name            'accounts';
    protected 
$_dependentTables = array('Bugs');
}

 

class 

class 

    protected 

    protected 

class 

    protected 

}

Products extends Zend_Db_Table_Abstract
{
    protected 
$_name            'products';
    protected 
$_dependentTables = array('BugsProducts');
}
Bugs extends Zend_Db_Table_Abstract
{
    protected 
$_name            'bugs';$_dependentTables = array('BugsProducts');$_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')
        )
    );
}
BugsProducts extends Zend_Db_Table_Abstract
{
    protected 
$_name 'bugs_products';$_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'关系进行说明)

以上定义关系。

从关联表中取数据:

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

 $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();

<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->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>()
例子:

 

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

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

$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();




热门内容

MySQL执行引擎有哪些

MyISAM: 优势 – 查询速度快 – 数据和索引压缩问题 – 表级锁 – 数据丢失 InnoDB: 优... ...

Centos7下yum搭建lnmp环境(yum安装方式)

我们都知道linux下安装软件主要有三种方式: 1.源码编译安装,即下载软件源代码,利用gcc g++ make 等编译 ...

\(^_^)/ Java实现各种排序算法

各种排序算法及其java程序实现 . 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 ... ...

hibernate空格导致的错误!

数据库中已经有两条记录,这是为了测试数据用的。 下面是我对hibernate中查询进行的测试.... package ...

上课思想分析过程

1.功能较多必须有菜单选择项2.针对题目避免重复时先将已生成的算式保存,然后将下一条生成的式子进行判断是否已生成,如果生 ...

存储过程不能删除之ORA-04043

同事问有一个存储过程在PL/SQL Developer中可以看到,但删除的时候报对象不存在。   ... ...

系统属性Properties历遍

package com.msmiles.test; import java.util.Enumeration; ... ...

在 linux x86-64 模式下分析内存映射流程

前言 在上一篇中我们分析了 linux 在 x86-32 模式下的虚拟内存映射流程,本章主要继续分析 linux 在 ... ...

一个过滤器类,过滤多个路径

<!-- 登录验证 --> <filter> <filter-name>... ...

网页中的平衡、对比、连贯和留白

网页中的平衡、对比、连贯和留白 <!-- Body Copy --> 网页设计中需要把握好很多原则和细节,... ...
好高兴啊

好高兴啊

  好高兴啊…..好高兴啊….终于发现了…..   ... ...

WCF技术剖析(卷1)之目录

第1章  WCF简介 (WCF Overview)      ... ...

EXT核心API详解(五)

[转载]EXT核心API详解(五)-Ext.EventManager/EventObject/CompositeElem... ...

xorg如何使用 xkbprint?

问题:手册中没有例子,我所尝试的每个文件都需要一些几何。$ xkbcomp/usr/share/x11/xkb/symb ...
织梦淘宝客常见问题

织梦淘宝客常见问题

一、下载安装 见官方帖子,不细说。http://bbs.dedecms.com/203194.html 在此强烈建议新手... ...

(转)批处理(bat)全盘搜索指定文件获取其完整路径方法大全

本文总结了4种实现全盘搜索指定文件获取其完整路径的bat批处理文件源码,有需要的朋友可以参考下 【方案一】fo... ...

Java线程讲解

一 线程的基本概念 线程是一个程序内部的顺序控制流.一个进程相当于一个任务,一个线程相当于一个任务中的一条执行路径. ... ...

css display:none和visibility:hidden和visible="false"区别

  如果在p的style中把visibility设为 hidden则p隐藏,但是它会占据空白空间,... ...

ASP.NET[1]

   有很多人学过ASP,用ASP做过网站,可是到ASP .NET环境下发现,变化真是太大了... ...

构建一个安全的软件系统时,可能遇到的风险及解决方案(未完)

随着汽车工业的发展,汽车早以不是那个由一堆零件组成的大机器,而是由机械和电子器件构成的整体系统。并且,这个... ...
VPS上安装ShadowSocks

VPS上安装ShadowSocks

shadowsocks 是一个轻量级隧道代理,用来穿过防火墙。 我的VPS机器安装的是CentOS系统、... ...

ResultSet 调用getString 抛出NullPointException问题的解决

在Java连接数据库时,有时候在ResultSet 调用getString (或其他类似的方法),有时候会抛出Nu... ...

浅谈OSIV与泛型DAO模式

open session in view  简称 OSIV 模式 在Hibernate中能更好的应... ...

数据库设计原理:数据建模的三个阶段

如果你在Google或者百度上搜索数据建模,相信可以搜索出很多关于数据建模的文章,但是你会发现其中绝大部分是理论、... ...

ajaxfileupload.js 文件上传

一,前台代码。 <input id="fileToUpload" type="... ...

ios的标志常量

1 dec 2 fixed 3 hex 4 internal 5 left 6 oct 7 right 8 scien ...

discuz删除垃圾帖子

有时候如果你的论坛被垃圾帖子占满后,会发现使用后台的删除功能还是有些慢, 我们需要先备份自己需要的帖子,然后进行下面的 ...

Hibernate的主配置文件hibernate.cfg.xml

1:hibernate的主配置文件的名字必须是hibernate.cfg.xml:   1.1:主配置文件主要分为三部分 ...

关于html base元素的使用

base元素可以用于设置页面嵌入的css文件或js文件链接的基地址。 例子: <h... ...

类型转换与强制转换

自动转换: 举一个例子:把一个小的东西放到一个大的盒子里,是件非常容易的事,不用做任何改变,在这里理解成自动转换。... ...