如何在 Kohana 中使用 ORM 连接表

Posted

技术标签:

【中文标题】如何在 Kohana 中使用 ORM 连接表【英文标题】:How to join tables using ORM in Kohana 【发布时间】:2013-11-27 21:35:40 【问题描述】:

正如您在我的历史中看到的那样,我对 kohana 有点陌生,但学习很快.. 我正在努力解决之前在 Kohana 3.3 中有效的一个奇怪问题

我想在两个数据库之间创建一个连接查询。我创建了 Model_Veiligen en Model_Veilingvoorkeur 模型,并将其作为 ORM 调用:

这是正确的连接查询:

 SELECT `vastprijs`, `veilingen`.`id` AS `id`, `veilingen`.`gid` AS `gid`, `veilingen`.`provincie` AS `provincie`, `veilingen`.`created` AS `created`, `veilingen`.`termtime` AS `termtime`, `veilingen`.`postcode` AS `postcode`, `veilingen`.`lat` AS `lat`, `veilingen`.`lng` AS `lng`, `veilingen`.`titel` AS `titel`, `veilingen`.`beschrijving` AS `beschrijving`, `veilingen`.`images` AS `images`, `veilingen`.`ip` AS `ip`, `veilingen`.`unique` AS `unique` FROM `veilingen` AS `veilingen` RIGHT JOIN `veilingvoorkeur` ON (`veilingen`.`id` = `vid`) ORDER BY `veilingen`.`created` DESC LIMIT 10

左下角:

SELECT `vastprijs`, `veilingen`.`id` AS `id`, `veilingen`.`gid` AS `gid`,     `veilingen`.`provincie` AS `provincie`, `veilingen`.`created` AS `created`,     `veilingen`.`termtime` AS `termtime`, `veilingen`.`postcode` AS `postcode`,     `veilingen`.`lat` AS `lat`, `veilingen`.`lng` AS `lng`, `veilingen`.`titel` AS `titel`,     `veilingen`.`beschrijving` AS `beschrijving`, `veilingen`.`images` AS `images`,     `veilingen`.`ip` AS `ip`, `veilingen`.`unique` AS `unique` FROM `veilingen` AS `veilingen`     LEFT JOIN `veilingvoorkeur` ON (`veilingen`.`id` = `vid`) ORDER BY `veilingen`.`created` DESC LIMIT 10

右连接输出:

[_object:protected] => Array ( [id] => [gid] => [provincie] => [created] => [termtime] => [postcode] => [lat] => [lng] => [titel] => [beschrijving] => [images] => [ip] => [unique] => [vastprijs] => 56 ) 

左连接输出:

[_object:protected] => Array ( [id] => 121 [gid] => 10 [provincie] => 9 [created] => 1385534362 [termtime] => 1386743962 [postcode] => 8031CJ [lat] => 52.528510 [lng] => 6.081043 [titel] => gdfgd [beschrijving] => fgfdgdfgfdsfsfd [images] => ["file_name":"5a5a7a7ef44.png","file_size":238687,"file_type":"image\/png","file_link":"uploads\/\/5a5a7a7ef44.png"] [ip] => 94.215.33.178 [unique] => [vastprijs] => )

我的左或右连接代码如下:

$veiling = ORM::factory('veilingen')
        ->select('vastprijs')
        ->join('veilingvoorkeur', 'RIGHT')
        ->on('veilingen.id', '=', 'vid')
        ->order_by('veilingen.created', DESC)
        ->limit(10)
        ->find_all();

我遇到的问题是我不了解has_many 和belongs_to,上面的示例以前有效,但现在不再有效。

如果我在 LEFT 中更改 RIGHT 会出现问题,它将输出 veilingen 表中的所有数据。但它忽略了vastprijs 字段的数据。但是,如果我打印 foreach 元素,我可以看到已经选择了该域。数据除外。

如果我使用右,而不是左。上面的故事发生了,但不是这样。 largeprijs 不是空的,veilingen 字段是空的。但显示出来了。


我的主要问题是,我如何将这 2 个表与 has_many 联系起来,但 veilingen 只有 has_one veilingvoorkeur。关键是 veilingen.id = veilingvoorkeur.vid

【问题讨论】:

那么问题是什么? 你为什么不使用has_many/belongs_to (1:n) 关系? 我刚刚添加了更多信息,我忘记了这个问题。提前致谢。也许你能解释一下如何建立模型之间的关系? veilingvoorkeurveilingen 中是否总是有相关项目(或者vid 可以为空)? Kingkero,vid永远不能为空,每个veilingen条目id在vid上都有一个veilingvoorkeur条目。 【参考方案1】:

我的主要问题是,我如何将这 2 个表与 has_many 联系起来,但 veilingen 只有 has_one veilingvoorkeur。关键是 veilingen.id = veilingvoorkeur.vid

问题在哪里? Kohana还提供has_one的可能性:

class Model_veilingen extends ORM 

    protected $_has_one = array(
        'veilingvoorkeur' => array(
            'model' => 'veilingvoorkeur',
            'far_key' => 'vid',
        ),
    );


既然关系总是有两个方面,你也需要定义另一个方面。 belongs_to 用于总是需要另一边的东西。

class Model_veilingvoorkeur extends ORM 

    protected $_belongs_to = array(
        'veilingen' => array(
            'model' => 'veilingen',
            'foreign_key' => 'vid',
        ),
    );


如果您不确定是使用foreign_key 还是far_key,this answer 应该可以帮助您。还要多解释一下关系:

A has_one B:A 中的一项与 B 中的一项或没有一项相关 A belongs_to B:A 中的一项总是与 B 中的一项相关

您的查询现在可以这样完成:

$veilings = ORM::factory('veilingen')->order_by('created', DESC')->limit(10)
    ->find_all();
foreach ($veilings as $veiling) 
    $veiling->veilingvoorkeur->find();
    print $veiling->veilingvoorkeur->vastprijs;

老实说,如果 $veiling 没有相关的 veilingvoorkeur,我不太确定该怎么做,但应该可以这样做(从想法)

    $veilingvoorkeur = $veiling->veilingvoorkeur->find();
    if (!empty($veilingvoorkeur))
        print $veilingvoorkeur->vastprijs;

我没有测试代码,如果它在某处失败,我希望至少澄清了如何使用关系来解决这个问题。

【讨论】:

外键是指指向其匹配id的cother表的键吗? @kingkero 正确(就像在 SQL 中一样) Database_Exception [1054]:“where 子句”中的未知列“veilingvoorkeur.veilingen_id”[SELECT veilingvoorkeur.id AS idveilingvoorkeur.vid AS vidveilingvoorkeur 987654343 @ AS startbodveilingvoorkeur 987654346 @ AS opbodveilingvoorkeur 987654350 @ veilingvoorkeur 987654352 veilingvoorkeur 987654353 @ 987654353 987654354@ = '124' LIMIT 1 ] 它看起来不像是一个连接查询,我收到一个奇怪的错误......他正在尝试加载 veilingvoorkeur.veilingen_id @kingkero 您是否正确定义了模型?我发布的只是关系本身的概述 我猜是这样,我将受保护的 has_one 和 belongs_to 插入到我的模型中,然后他给了我那个错误。

以上是关于如何在 Kohana 中使用 ORM 连接表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kohana 3 中链接多个 ORM 关系?

Kohana 3.0.x ORM:读取数据透视表中的其他列

Kohana ORM - 我该怎么做?

对 Kohana ORM 有帮助吗?

已达到 PHP 最大数据库连接数 - 使用 Kohana/ORM 启动连接

Kohana 2.3.4 ORM - 删除数据透视表关系