2013-02-19 2 views
0

우선,이 질문의 길이에 대해 사과하고 싶습니다. 나는 배경 지식없이 제 질문을 올바르게 어떻게 풀어 낼지 몰랐습니다. 나와 함께 견뎌주십시오.두 개의 간단한 SQL 쿼리를 Doctrine으로 변환

나는 내 자신의 사용자 지정 데이터베이스 액세스 스키마에서 Doctrine으로 기술을 연마하는 데 사용하는 간단한 응용 프로그램을 변환하고 있습니다. Doctrine을 여러 가지 이유로 선택했습니다. 그 중 가장 적은 것이 정기적으로 일상 업무에서 사용된다는 것입니다. 나는 또한 Doctrine이 일반적으로 많은 기능을 추가하는 동안 방해받지 않는 꽤 얇은 (나타나는) 레이어라는 것을 좋아합니다.

데이터베이스의 users 테이블에 대한 데이터 액세스 계층을 Doctrine으로 변환했습니다. 그것은 몇 세밀한 부분을 제외하고, (단순히 getter 및 setter) 매우 하찮은이다 :

  • 내가 User 객체가 기본 ArrayCollection 생성자에서 인스턴스화 한 사용자 정의 일부 특정 쿼리에 대한 저장소 및
  • 이 필요합니다

namespace model\entities; 

/** 
* @Entity(repositoryClass="model\repositories\UserRepository") 
* @Table(name="users") 
*/ 
class User{ 
    /* snip variables */ 

    /** 
    * @OneToOne(targetEntity="Authentication", mappedBy="user", cascade="persist") 
    */ 
    private $authentication; 

    /** 
    * @OneToMany(targetEntity="Contact", mappedBy="user", cascade="persist") 
    */ 
    private $contacts; 

    public function __construct() { 
     $this->contacts = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /* snip getters and setters */ 
} 

이전의 스키마에는 users 테이블의 하위 집합을 선택한 두 개의 사용자 지정 쿼리가있었습니다.

는 그들은 :

public function search($term = null){ 
    if(!$term){ 
     $sql = "SELECT * 
       FROM 
       " . $this->tableName . " 
       ORDER BY 
        lname ASC, 
        fname ASC"; 
     $res = $this->db->q($sql); 
    } 
    else{ 
     $sql = "SELECT * 
       FROM 
       " . $this->tableName . " 
       WHERE 
        lname LIKE ? 
        OR fname LIKE ? 
        OR CONCAT(fname, ' ', lname) LIKE ? 
       ORDER BY 
        lname ASC, 
        fname ASC"; 
     $values = array('%' . $term . '%', '%' . $term . '%', '%' . $term . '%'); 
     $res = $this->db->qwv($sql, $values); 
    } 

    return $this->wrap($res); 
} 

하고 :

$this->db 제로 얇은 PHP PDO wrapper$this->wrap does magic이다
public function getAllWithRestrictions(){ 
    $sql = "SELECT * 
      FROM 
      " . $this->tableName . " 
      WHERE 
       userid IN 
       (
        SELECT 
         userid 
        FROM 
         " . $this->uiPre . "authentications 
        WHERE 
         resetPassword = 1 
         OR disabled = 1 
       )"; 
    $res = $this->db->q($sql); 

    return $this->wrap($res); 
} 

/단일/다중 행 반환 data objects로 변환.

이제 Doctrine으로 변환하는 것이 매우 쉬울 것이라고 생각했습니다. getAllWithRestrictions의 경우 단순히 ->where, ->orWhere으로 설정됩니다. 맞습니까? 나는 더 이상 모른다.

나는 내 쿼리를 구성하려고 사용이 유래 질문을 찾았지만, 나는 오류가 발생한 후 오류로 실행 해요, 그리고 내가 갈 필요가 얼마나 멀리 토끼 구멍 아래로 확실하지 않다 :

Doctrine: Multiple (whereIn OR whereIn) query?
Doctrine - or where?

내 사용자 정의 저장소는 현재 다음과 같습니다,하지만 난 그것이 내가 오랫동안 함께 바이올린을 켜는 봤는데으로 수정 근처에도 말할 수없고, 단지의 SQL Multiple sorting and grouping
Order by multiple columns with Doctrine
남자 이름- 내가 무슨 생각의 CLC에서는 작동 될 수 있습니다

<?php 
namespace model\repositories; 
use Doctrine\ORM\EntityRepository; 
use Doctrine\ORM\Query\Expr; 

class UserRepository extends EntityRepository{ 
    public function search($term){ 
     if(!$term){ 
      return $this 
        ->_em 
        ->createQuery('SELECT u FROM model\entities\User u') 
        ->addOrderBy('u.lname') 
        ->addOrderBy('u.fname') 
        ->getResult(); 
     } 
     else{ 
      $qb  = $this->_em->createQueryBuilder(); 

      $qb ->select(array('u')) 
       ->from('model\entities\User', 'u') 
       ->where($qb->expr()->like('u.lname', '?1')) 
       ->orWhere($qb->expr()->like('u.fname', '?2')) 
       ->orWhere($qb->expr()->like('CONCAT(u.fname, \' \', u.lname)', '?3')) 
       ->addOrderBy('u.lname') 
       ->addOrderBy('u.fname') 
       ->setParameters(
        array(
         1 => $term, 
         2 => $term, 
         3 => $term 
        ) 
       ); 

      $query = $qb->getQuery(); 
      return $query->getResult(); 
     } 
    } 

    public function getAllWithRestrictions(){ 
     $qb  = $this->_em->createQueryBuilder(); 

     $qb ->select(array('u')) 
      ->from('model\entities\User', 'u') 
      ->add('where', $qb->expr()->orx(
       $qb->expr()->eq('u.disabled', '1'), 
       $qb->expr()->eq('u.resetPassword', '1') 
      )); 

     $query = $qb->getQuery(); 
     return $query->getResult(); 
    } 
} 

편집 : 난 그냥 내가 잘못 테이블에 getAllWithRestrictions 쿼리를하고 있어요 것을 깨달았다. (이 authentications해야합니다) 어떤 경우, 원인이되는 검색 방법입니다 내 지금 이슈. 그러나, 나는 또한 $qb->expr()->eq('u.Authentication.disabled = '1')과 같은 것을 어떻게하는지 알 필요가 있으며, DQL이 실제로 어떻게 작동하는지 전혀 알지 못합니다.

  • Doctrine\ORM\Query\QueryException: [Syntax Error] line 0, col 99: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got ','

그러나 I'v에 의해

  • Fatal error: Uncaught exception 'Doctrine\ORM\Query\QueryException' with message 'SELECT u FROM model\entities\User u WHERE u.lname LIKE ?1 OR u.fname LIKE ?2 OR CONCAT(u.fname, ' ', u.lname) LIKE ?3 ORDER BY u.lname ASC, u.fname ASC'

을 따라

내가 지금지고있어 특정 오류가있다 e는 DQL/Query Builder를 구성하는 방법에 따라 다양한 문제가있었습니다.

이번에도이 두 SQL 쿼리가 Doctrine/DQL로 변환하는 것이 간단 할 것으로 기대했습니다. Doctrine을 통해 원시 SQL을 사용하지 않고이 작업을 수행하고 싶습니다. 반드시 쉬워야합니다. 누구나 우아한 Doctrine 쿼리를 구성하는 방법을 알고 있습니까? 교리의 CONCAT 함수 파서 따르면

답변

1

, 단지 그래서

->orWhere($qb->expr()->like('CONCAT(u.fname, \' \', u.lname)', '?3')) 

->orWhere($qb->expr()->like('CONCAT(u.fname, u.lname)', '?3')) 

이 여야 쉼표로 구분 2 개 파라미터

//Doctrine/ORM/Query/AST/Functions/ConcatFunction.php 
$parser->match(Lexer::T_IDENTIFIER); 
$parser->match(Lexer::T_OPEN_PARENTHESIS); 

$this->firstStringPrimary = $parser->StringPrimary(); 
$parser->match(Lexer::T_COMMA); 
$this->secondStringPrimary = $parser->StringPrimary(); 

$parser->match(Lexer::T_CLOSE_PARENTHESIS); 

소요 어떤 오류도 던지지 않을 것이지만 실제로는 그렇지 않을 수도 있습니다. 에드. 이 경우에는 ('CONCAT(u.fname, CONCAT(\' \', u.lname))' 같은 중첩 된 CONCAT을 추가하여 오류를 해결 도움이되는) 다른 기능을 해결할 수 있습니다 위 @ Broncha의 대답에 추가 CONCAT :

+0

오, 왜 교리는 [MySQL의 기능]에 대한 다른 정의를 정의 않습니다 http://dev.mysql.com/doc을 : 다음과 같이 가입에 WHERE 조항을 추가, 필요한 엔티티에 합류 /refman/5.0/en/string-functions.html#function_concat)? 그것은 매우 걱정입니다. – rockerest

1

에 대한 사용자 정의 기능을 출시 할 것 (

$qb ->select(array('u')) 
    ->from('model\entities\User', 'u') 
    ->leftJoin('u.authentication', 'a') 
    ->add('where', $qb->expr()->orx(
     $qb->expr()->eq('a.disabled', '1'), 
     $qb->expr()->eq('a.resetPassword', '1') 
    )); 
관련 문제