【问题标题】:CakePHP query additions in controller控制器中的 CakePHP 查询添加
【发布时间】:2011-03-27 18:11:35
【问题描述】:

我正在将原始 PHP 代码迁移到 CakePHP 并且遇到了一些问题。由于我在查询到 ORM 转换时遇到大问题,我临时使用原始 SQL。一切都很顺利,但我遇到了丑陋的代码,并不知道如何让它变得漂亮。我创建了DealersController 并添加了function advanced($condition = null)(它将使用参数1-15 和69 从AJAX 调用)。函数看起来像:

switch ($condition) {
  case '1':
    $cond_query = ' AND ( (d.email = \'\' OR d.email IS NULL) )';
  break;
  case '2':
    $cond_query = ' AND (d.id IN (SELECT dealer_id FROM dealer_logo)';
  break;
  // There are many cases, some long, some like these two
}

if($user_group == 'group_1') {
  $query = 'LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} elseif ($user_group == 'group_2'){
  $query = 'A LITLE BIT DIFFERENT LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} else {
  $query = 'A LITLE MORE BIT DIFFERENT LONG QUERY WITH 10+ TABLES JOINING' . $cond_query;
} 

// THERE IS $this->Dealer->query($query); and so on

所以.. 如您所见,代码看起来很难看。我有两种变体:

1) 取出查询添加并为每个条件制作模型方法,然后将这些条件分离为函数。但这不是 DRY,因为主要的 3 个大查询几乎相同,如果我需要同时更改某些内容 - 我将需要更改 16+ 个查询。

2) 制作小的可重用模型方法/查询,这会从 DB 小块数据中提取出来,然后不要使用原始 SQL,而是使用方法。这会很好,但性能会很低,我需要它尽可能高。

请给我建议。谢谢!

【问题讨论】:

    标签: sql cakephp model controller


    【解决方案1】:

    如果您关心 CakePHP 如何对每个连接表进行数据库查询,您可能会发现Linkable 行为可以帮助您减少查询数量(其中连接是一个表上的简单关联)。

    否则,我发现在模型级别创建简单的数据库查询方法来获取较小的信息,然后将它们组合起来,是一种好方法。它允许您清楚地概述您的代码的功能(通过内联文档)。如果您可以迁移到使用 CakePHP 的 find 方法而不是原始查询,那么您将使用 conditions 数组语法。因此,您可以解决问题的一种方法是在您的模型类上使用公共函数,将它们的适当条件附加到输入的条件数组中。例如:

    class SomeModel extends AppModel {
        ...
        public function addEmailCondition(&$conditions) {
            $conditions['OR'] = array(
                'alias.email_address' => null, 
                'alias.email_address =' => ''
            );
        }
    }
    

    您可以调用这些函数来构建一个大的conditions 数组,然后您可以使用该数组从控制器(或者如果您想在模型层包含所有数据,则从模型中)检索您想要的数据。请注意,在上面的示例中,conditions 数组是通过引用传递的,因此可以就地编辑它。另请注意,数组中任何现有的“或”条件都将被此函数覆盖:在将新条件与任何现有条件合并方面,您的真正解决方案必须更智能。

    不要担心“假设的”性能问题 - 如果您尝试查询并且它们太慢,那么您可以担心如何提高性能。但是对于初学者来说,尽量把代码写得干净利落。

    您可能还需要考虑将 function advanced() 调用拆分为多个控制器操作,这些控制器操作按其 condition 查询的相似性分组。

    最后,如果您还没有检查过,这里是本书关于从模型中检索数据的条目。可能有一些你没见过的技巧:http://book.cakephp.org/view/1017/Retrieving-Your-Data

    【讨论】:

    • 所以.. 首先感谢 Linkable - 我读到它并认为它很有帮助!
    • 第二次 - 你提议在模型find_big_query() 中创建一个函数和更小的函数add_something_tofunction_find_big_query()?也许在模型公共变量additional_query_string 中创建并添加来自控制器的添加?什么是“最佳方式”?
    • 在不了解您的数据库架构的情况下,我无法就如何拆分查询提出适当的建议;你能说得更具体点吗?
    • 如果您能够迁移到使用 Cake 的 find 方法,使用 conditions 而不是构建查询,那么一种方法可能是在 Model 类上添加公共函数来附加所需的条件到输入的条件数组。我会在答案中举个例子。
    • 我认为这是我需要的!谢谢。
    【解决方案2】:

    如果查询的基本部分相同,您可以有一个函数来生成该部分查询,然后使用其他小函数附加不同​​的 where 条件等。

    【讨论】:

    • 没有。我认为最好的方法是摆脱查询并使用 Cake 函数,但如果你没有时间,你至少可以划分代码:)
    • 所以...那么最好的方法是使用 Linkable (如果需要)并使用 model->find() 方法而不是查询,并在每个 switch::case 中调用此方法?这是最好的方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多