【问题标题】:Doctrine2 split Query BuilderDoctrine2 拆分查询生成器
【发布时间】:2014-07-31 08:18:11
【问题描述】:

我正在使用 QueryBuilder 通过 Doctrine2 执行复杂的查询。

我想拆分此查询以定义或不定义某些条件。

然后看起来像这样:

$logs = $em->getRepository("Shs\Entity\Log")
           ->createQueryBuilder("log")
           ->where("log.client = :client")
           ->setParameter("client", $client);

if($search != ""){
    $logs->andWhere("log.name LIKE :search")
         ->setParameter("search", "%" . $search . "%");
}

$logs->addOrderBy("log.date", "DESC")
     ->getQuery()->execute();

但是这似乎不起作用。

如果我把它写在一个单独的块中,它会起作用:

$logs = $em->getRepository("Shs\Entity\Log")
           ->createQueryBuilder("log")
           ->where("log.client = :client")
           ->andWhere("log.name LIKE :search")
           ->setParameter("search", "%" . $search . "%")
           ->setParameter("client", $client)
           ->addOrderBy("log.date", "DESC")
           ->getQuery()->execute();;

如果我每次都重新定义 $logs 但我不明白为什么:

$logs = $em->getRepository("Shs\Entity\Log")
           [...]
           ->setParameter("client", $client);

if($search != ""){
    $logs = $logs->andWhere("log.name LIKE :search")
         ->setParameter("search", "%" . $search . "%");
}

$logs = $logs->addOrderBy("log.date", "DESC")
     ->getQuery()->execute();

在 QueryBuilder 类中,我看到 add 函数有一个参数 $append=false。 addOrderBy 函数(例如)调用 add 函数但将 $append 设置为 true :

public function addOrderBy($sort, $order = null)
{
    return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), true);
}

如果我强制 $append 为 false,它也可以,但我不会碰这个类。

实现我想做的最好的方法是什么?我应该使用 $qb->add() 而不是 $qb->where() 等,还是有办法使用 $qb->where() 来做到这一点?

非常感谢您的帮助!

【问题讨论】:

    标签: zend-framework doctrine-orm


    【解决方案1】:

    如果我每次都重新定义 $logs 但我不明白为什么:

    我猜您在复制/粘贴查询时可能会在其他地方遇到错误。考虑区分日志集合和查询生成器。比如:

    $qb = $em->getRepository("Shs\Entity\Log")
           ->createQueryBuilder("log")
           ->where("log.client = :client")
           ->setParameter("client", $client);
    
    if($search != ""){
        $qb->andWhere("log.name LIKE :search")->setParameter("search", "%" . $search . "%");
    }
    
    $qb->addOrderBy("log.date", "DESC");
    
    $logs = $qb->getQuery()->getResults();
    

    使用execute()方法也有点奇怪。通常你会使用 getResults() 的一些变体来进行查询。

    【讨论】:

    • 它有效,我明白了,谢谢! :) 可以拆分它,这是合乎逻辑的,因为它每次都会返回自己,但我想我没有得到结果,因为我混淆了 qb 和结果......所以 $logs = $qb->getQuery()- >execute() 解决了这个问题,显然不需要多次重新定义 $logs。我也会收到有关 getResult() 的通知。 ;)
    【解决方案2】:

    查看文档 (http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html)。

    我认为您应该通过以下代码实现:

    $logs = $em->createQueryBuilder()
               ->select("log")
                ->from("Shs\Entity\Log log")
               ->where("log.client = :client")
               ->setParameter("client", $client);
    
    if($search != ""){
        $logs->andWhere("log.name LIKE :search")
             ->setParameter("search", "%" . $search . "%");
    }
    
    $logs->addOrderBy("log.date", "DESC")
         ->getQuery()->execute();
    

    【讨论】:

    • ->from("Shs\Entity\Log", "log").谢谢,但它并没有解决问题...同样,如果我写 $logs = $logs->... 它可以工作。
    • 是的,这也应该有效(我认为两者都有可能)。老实说,我不明白这个问题。也许尝试重新定义或更具体。
    • 如果我回显 $logs->getQuery()->getSQL():您的代码显示“SELECT log FROM Shs\Entity\Log log WHERE log.client = :client AND log.name LIKE :搜索 ORDER BY log.date DESC”。当我将它写在一个块中时,它显示“SELECT l0_.id AS id0, l0_.name AS name1, l0_.date AS date2 FROM logs l0_ WHERE l0_.client_id = ? AND l0_.name LIKE ? ORDER BY l0_.date DESC "
    • 当您从存储库(而不是直接从实体管理器)创建查询构建器时,无需使用 select 或 from 子句。存储库会为您解决这些问题。
    猜你喜欢
    • 1970-01-01
    • 2012-04-06
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多