2011-03-27 7 views
0

원시 PHP 코드를 CakePHP로 마이그레이션 중이며 몇 가지 문제가 있습니다. ORM 변환 쿼리에 큰 문제가 있으므로 임시 SQL을 사용합니다. 모두 멋지게 나옵니다. 그러나 추한 코드를 만났고 정말 아름답게 만드는 방법을 모릅니다. DealersController을 만들고 function advanced($condition = null)을 추가했습니다 (매개 변수 1-15 및 69의 AJAX에서 호출됩니다). 함수는 다음과 같습니다.컨트롤러에 CakePHP 쿼리 추가.

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) 모든 조건에 대해 질의를 추가하고 모델 방법을 만든 다음, 이러한 조건은 기능과 분리된다. 그러나 주요 3 개의 큰 쿼리가 거의 동일하기 때문에 DRY가 아닙니다. 한 가지를 변경해야 할 경우 16 개 이상의 쿼리를 변경해야합니다.

2) 작은 재사용 가능한 모델 방법/쿼리가 데이터베이스의 작은 조각에서 나올 수 있도록 만든 다음 원시 SQL을 사용하지 않고 방법으로 재생합니다. 그것은 좋을 것이나, 성과는 낮을 것이고 나는 그것을 가능한 한 높이 필요로한다.

제게 조언을주십시오. 고맙습니다! 쿼리의 기초 부분이 동일한 경우

답변

0

당신이 만약 ' CakePHP가 조인 된 모든 테이블에 대해 데이터베이스 쿼리를 만드는 방법에 대해 염려한다면 Linkable 동작은 쿼리의 수를 줄이는 데 도움이 될 수 있습니다 (조인은 하나의 테이블에서 간단한 연결 임).

그렇지 않으면 작은 정보를 얻기 위해 모델 수준에서 간단한 데이터베이스 쿼리 메서드를 만든 다음 나중에 결합하는 것이 좋은 방법이라는 것을 알았습니다. 코드를 통해 인라인 문서를 통해 명확하게 윤곽을 잡을 수 있습니다. 원시 쿼리 대신 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 쿼리의 유사성으로 그룹화 된 여러 컨트롤러 작업으로 나누는 것을 고려할 수도 있습니다.

마지막으로 체크 아웃하지 않은 경우 모델에서 데이터 검색에 대한 책 항목을 참조하십시오. 이전에는 보지 못했던 몇 가지 트릭이있을 수 있습니다. http://book.cakephp.org/view/1017/Retrieving-Your-Data

+0

그래서 .. Linkable에 대한 첫 번째 감사에 대해 - 나는 그것에 대해 읽고 그것을 매우 도움이된다고 생각합니다! – Orbitum

+0

두번째로 - find_big_query() 모델과 add_something_tofunction_find_big_query() 함수가 하나 더 작다. 아마도 모델의 public 변수'additional_query_string'을 만들고 컨트롤러에서 추가 된 내용을 추가 할 것인가? "가장 좋은 방법은 무엇입니까?" – Orbitum

+0

데이터베이스 스키마에 대해 알지 못해도 쿼리를 분할하는 방법에 대해 적절한 권장 사항을 만들 수 없습니다. 좀 더 구체적으로 부탁해 주시겠습니까? – tokes

0

, 당신은 쿼리의 일부를 생성하는 기능을 가지고, 그리고 다른를 추가 할 다른 작은 기능을 사용할 수있는 곳 조건 등

+0

그럼 좋은 접근 방법이라고 생각하십니까? "가장 좋은 방법은"? – Orbitum

+0

아니요. 가장 좋은 방법은 쿼리를 없애고 Cake 함수를 사용하는 것이지만 시간이 없다면 코드를 최소한 구획화 할 수 있다고 생각합니다. –

+0

그럼 ... 가장 좋은 방법은 Linkable (필요한 경우)을 사용하고 쿼리 대신 model-> find() 메서드를 만들고 각 switch :: case에서이 메서드를 호출해야합니까? 이것이 최선의 방법일까요? – Orbitum

관련 문제