我正在将原始PHP代码迁移到CakePHP并遇到一些问题。由于我对ORM转换的查询存在很大问题,因此临时使用原始SQL。一切都很顺利,但我遇到了丑陋的代码,并不知道如何让它变得美丽。我做了DealersController
并添加了function advanced($condition = null)
(它将从AJAX中调用参数1-15和69)。功能看起来像:
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但使用方法。这会很好,但性能会很低,我需要它尽可能高。
请给我建议。谢谢!
答案 0 :(得分:0)
如果查询的基本部分相同,则可以使用函数生成查询的该部分,然后使用其他小函数追加不同的where条件等。
答案 1 :(得分:0)
如果您担心CakePHP如何为每个连接表进行数据库查询,您可能会发现Linkable行为可以帮助您减少查询数(其中连接是一个表上的简单关联) )。
否则,我发现在Model级别创建简单的数据库查询方法来获取较小的信息,然后将它们组合起来是一种很好的方法。它允许您清楚地概述您的代码所做的事情(通过内联文档)。如果您可以迁移到使用CakePHP的find
方法而不是原始查询,那么您将使用conditions
数组语法。因此,解决问题的一种方法是在Model类上使用公共函数,将其适当的条件附加到输入的条件数组。例如:
class SomeModel extends AppModel {
...
public function addEmailCondition(&$conditions) {
$conditions['OR'] = array(
'alias.email_address' => null,
'alias.email_address =' => ''
);
}
}
您可以调用这些函数来构建一个大的conditions
数组,然后您可以使用该数组从控制器中检索所需的数据(如果要在模型层中包含所有数据,则从模型中检索) 。请注意,在上面的示例中,conditions
数组正在通过引用传递,因此可以在适当的位置进行编辑。另请注意,此函数将覆盖数组中任何现有的“OR”条件:在将新条件与任何现有条件合并方面,您的真正解决方案必须更加智能。
不要担心“假设”的性能问题 - 如果您尝试查询并且速度太慢,那么您可以担心如何提高性能。但对于初学者来说,尽可能干净地编写代码。
您还可以考虑将function advanced()
调用拆分为多个控制器操作,这些操作按照condition
查询的相似性进行分组。
最后,如果你还没有检查出来,这是Book的从模型中检索数据的条目。可能有一些你以前没见过的技巧:http://book.cakephp.org/view/1017/Retrieving-Your-Data