初探 Zend_Db_Table Relationships (一)

本文介紹了如何在Zend Framework中實現數據庫表之間的一對多關聯。通過示例展示了如何配置Articles和Categories兩個表的關聯關係,並提供了代碼示例以展示如何查詢相關數據。

http://blog.roodo.com/jaceju/archives/4170901.html

 

早上四點半就醒了...睡不著,想說研究一下 Zend Framework DB 一對多的關連。先前一直搞不定其中的關係,沒想到簡單玩了一下,竟然就搞定了 (可見手冊我根本就沒看懂...Orz) 。

這裡記一下,以免之後又忘記了。

 

資料表範例

這裡我用文章 (Article) 及文章分類 (Category) 來做為例子,它們的 DB Schema 如下:

 

CREATE TABLE IF NOT EXISTS `articles` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `category_id` int(10) unsigned NOT NULL,
  `title` varchar(200) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `table1_id` (`category_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

INSERT INTO `articles` (`id`, `category_id`, `title`) VALUES
(1, 3, 'Zend_Db_Table'),
(2, 3, 'Zend_Controller_Action'),
(3, 2, 'jQuery'),
(4, 2, 'Prototype');

CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `parent_id` int(10) unsigned NULL,
  `name` varchar(200) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

INSERT INTO `categories` (`id`, `parent_id`, `name`) VALUES
(1, NULL, 'PHP'),
(2, NULL, 'JavaScript'),
(3, 1, 'Zend Framework');

 

程式碼架構

這裡主要我是拿 RobGetting Started with the Zend Framework 裡面範例來修改,詳細架構就先看看後面附的下載檔。

不過也不一定需要用這樣的架構才能跑 ZF ,這是因為我偷懶不想寫太多不相關的程式,所以直接拿別人的來改。事實上我們可以把 Zend_Db 獨立出來使用,只是這樣要寫的東西就會比較複雜一點點,跟我要研究的東西無關。

 

範例下載

下載位置

 

說明

首先我們需要兩個繼承 Zend_Db_Table_Abstract 的 Class ,它們分別是 Articles 和 Categories :

class Articles extends Zend_Db_Table_Abstract
{
    protected $_name = 'articles';
}

class Categories extends Zend_Db_Table_Abstract
{
    protected $_name = 'categories';
}

 

因為大部份工作已經被 Zend_Db_Table_Abstract 做掉了,所以 Articles 和 Categories 只要很簡單的指定 $_name 屬性即可;這樣一來, Articles 和 Categories 兩個 Classes 就能對應到 articles 和 categories 兩個資料表。

不過這樣還沒有辦法讓這兩個資料表在程式碼裡產生關連,我們必須在 Articles 和 Categories 這兩個 Classes 額外定義一些資訊,讓它們能互相認識。首先我們在 Articles Class 裡加上 $_referenceMap 屬性:

class Articles extends Zend_Db_Table_Abstract
{
    protected $_name = 'articles';

    protected $_referenceMap    = array(
        'Category' => array( // 給這個關連一個名字
            'columns'           => 'category_id', // 對應到 articles.category_id
            'refTableClass'     => 'Categories',  // 對應到 Categories Class
            'refColumns'        => 'id',          // 對應到 categories.id
        ),
    );
}

 

$_referenceMap 屬性是用來宣告要透過哪個欄位來和另一個資料表做關連,就上面的例子來看,我們可以很清楚的看到是 articles.category_id 關連到 categories.id 。然而 $_referenceMap 屬性可以同時定義多組關連,但為了簡化以便於理解,這裡我只用了一組。

在這裡的 $_referenceMap 屬性裡主要有三個項目:

  • columns :表示目前資料表關連到另一個資料表的欄位,一般就是 Foreign Key (FK) 。

  • refTableClass :關連資料表所對應的 Class ,這裡要注意大小寫。

  • refColumns :關連資料表所對應的欄位,一般就是 Primary Key (PK) 。

註: $_referenceMap 其實還有其他可設定的項目,這裡暫不介紹。

 

接著 Categories 這個 Class 也必須定義一個 $_dependentTables 屬性,宣告與 categories 有關連的資料表名稱;這是為了保證我們在透過 Categories Class 刪除資料時,能一併刪掉關連資料表裡的資料 (這裡我還在研究,尚無實例) 。

class Categories extends Zend_Db_Table_Abstract
{
    protected $_name = 'categories';

    protected $_dependentTables = array('Articles');  // 對應到關連的 Table Class
} 

註:事實上 $_dependentTables 屬性在目前這個例子裡可以不加,因為我們還用不到關連更新或刪除的功能。

 

現在我們可以在 IndexController::indexAction 裡測試看看:

class IndexController extends Zend_Controller_Action
{
    function indexAction()
    {
        $categories = new Categories();

        $zendframework = $categories->find(3)->current();
        $this->view->articles = $zendframework->findDependentRowset('Articles');
    }
}

 

其中 findDependentRowset 是 Zend_Db_Table_Abstract 提供的方法,它可以幫我們找出關連資料表的所有資料。我們在 index.pthml 裡可以將取得的結果表列出來:

<?php
var_dump($this->articles->toArray());
?>

 

 

是不是很簡單呢?

那麼第二個問題來了,如果我們要讓 categories._parent_id 和 categories.id 產生關連呢?

其實仿照上面的做法,我們只需要在 Categories Class 裡動手腳即可:

 

class Categories extends Zend_Db_Table_Abstract
{
    protected $_name = 'categories';

    protected $_referenceMap    = array(
        'ParentCategory' => array(
            'columns'           => 'parent_id',   // 對應到 categories.parent_id
            'refTableClass'     => 'Categories',  // 對應到 Categories Class
            'refColumns'        => 'id',          // 對應到 categories.id
        ),
    );

    protected $_dependentTables = array('Articles', 'Categories');   // 對應到關連的 Table Class
}

 

 

也就是說,我們在 Categories Class 加入一個 $_referenceMap 屬性關連到自己,然後在 $_dependentTables 加入自己。

接著在 IndexController::indexAction 中測試一下:

class IndexController extends Zend_Controller_Action 
{
    function indexAction()
    {
        $categories = new Categories();

        $php = $categories->find(1)->current();
        $this->view->subcategories = $php->findDependentRowset('Categories');

        $zendframework = $categories->find(3)->current();
        $this->view->articles = $zendframework->findDependentRowset('Articles');
    }
}

 

在 index.phtml 裡顯示結果:

<?php
var_dump($this->subcategories->toArray());
?>

 

以上就是簡單的 Zend_Db_Table_Actract 一對多關連取得資料集的方式,謝謝收看,下次見。 (補眠去...什麼?已經天亮要上班了喔?)

Delphi 12.3 作为款面向 Windows 平台的集成开发环境,由 Embarcadero Technologies 负责其持续演进。该环境以 Object Pascal 语言为核心,并依托 Visual Component Library(VCL)框架,广泛应用于各类桌面软件、数据库系统及企业级解决方案的开发。在此生态中,Excel4Delphi 作为个重要的社区开源项目,致力于搭建 Delphi 与 Microsoft Excel 之间的高效桥梁,使开发者能够在自研程序中直接调用 Excel 的文档处理、工作表管理、单元格操作及宏执行等功能。 该项目以库文件与组件包的形式提供,开发者将其集成至 Delphi 工程后,即可通过封装良好的接口实现对 Excel 的编程控制。具体功能涵盖创建与编辑工作簿、格式化单元格、批量导入导出数据,乃至执行内置公式与宏指令等高级操作。这机制显著降低了在财务分析、报表自动生成、数据整理等场景中实现 Excel 功能集成的技术门槛,使开发者无需深入掌握 COM 编程或 Excel 底层 API 即可完成复杂任务。 使用 Excel4Delphi 需具备基础的 Delphi 编程知识,并对 Excel 对象模型有定理解。实践中需注意不同 Excel 版本间的兼容性,并严格遵循项目文档进行环境配置与依赖部署。此外,操作过程中应遵循文件访问的最佳实践,例如确保目标文件未被独占锁定,并实施完整的异常处理机制,以防数据损毁或程序意外中断。 该项目的持续维护依赖于 Delphi 开发者社区的集体贡献,通过定期更新以适配新版开发环境与 Office 套件,并修复已发现的问题。对于需要深度融合 Excel 功能的 Delphi 应用而言,Excel4Delphi 提供了经过充分测试的可靠代码基础,使开发团队能更专注于业务逻辑与用户体验的优化,从而提升整体开发效率与软件质量。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值