簡體   English   中英

如何在Doctrine和ORM之間使用查詢

[英]How to make a query using Between with Doctrine and ORM

使用Docrtine 2和Zend Framework 2,我有一個像這樣的服務:

class TransactionService 
{
    public function __construct(TransactionMapperInterface $transactionMapper)
    {
        $this->transactionMapper = $transactionMapper;
    }

    public function findBy($conditions = array(), $order = array(), $limit = null, $offset = null)
    {
        return $this->transactionMapper->findBy($conditions, $order, $limit, $offset);
    }
}

但是我需要像這樣的結果查詢BETWEEN條件:

select * from transactions where created between '2014-02-01' and '2014-03-01';

這可以用findBy方法嗎?

簡而言之,沒有。 findBy僅用於簡單查詢,而您的BETWEEN不屬於其中。

但是,它可以相對簡單地完成:我將使用Doctrine\\ORM\\Query\\Filter\\SQLFilter進行這種查詢,這是Doctrine 2.2以來的一項新功能。

它的工作方式是創建一個從基本SQLFilter類擴展的類,並向其添加您自己的過濾器約束。 啟用過濾器后,之后基於該特定實體的任何查詢都將應用此過濾器。

對於您的特定問題,您可以執行以下操作(假設transactions表實際上是一個名為ORM\\Entity\\Transactions

<?php

namespace ORM\Filter;

use Doctrine\ORM\Mapping\ClassMetaData;
use Doctrine\ORM\Query\Filter\SQLFilter;

/**
 * This filter filters on records between two given dates.
 */
class BetweenFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetaData $targetEntity, $targetTableAlias)
    {
        // First check if the entity implements the BeteenAware interface
        if (!$targetEntity->reflClass->implementsInterface('ORM\Filter\BetweenAware')) {
            return "";
        }

        // We know now that our table supports the between entity, please note
        // that getParameter automatically quotes variables
        return sprintf(
            '(created BETWEEN %s AND %s)',
            $this->getParameter('betweenFrom'),
            $this->getParameter('betweenTo')
        );
    }
}

現在,我們要做的是創建一個ORM\\Filter\\BetweenAware接口,我們的ORM\\Entity\\Transactions需要實現該接口,以便Doctrine知道可以在這些字段上進行過濾。 該接口僅用於標識目的,因此非常短。

<?php

namespace ORM\Filter;

/**
 * BetweenAware defines that an Entity is able to filter on the
 * 'created' field.
 */
interface BetweenAware {}

此時剩下的就是添加過濾器,設置參數並啟用過濾。

// We'll ASSUME that the $config variable is a valid Doctrine configuration object retrieved 
// by instances such as `Setup::createAnnotationMetadataConfiguration`. On the other hand
// the variable $connection is assumed to contain valid connection details.

// First add the filter to the configuration
$config->addFilter('between', 'ORM\Filter\BetweenFilter');

// Now create the EntityManager
$entityManager = EntityManager::create($connection, $config);

// We will now enable our filter and set the parameters
$entityManager
->getFilters()
->enable('between')
->setParameter('betweenFrom', '2014-02-01')
->setParameter('betweenTo', '2014-03-01')
;

// Now for the moment supreme, lets get all the records back
$records = $entityManager
->getRepository('ORM\Entity\Transactions')
->findAll()
;

我沒有測試代碼,所以不確定它是否沒有錯誤,但這絕對是過濾記錄的一種好方法,而不會造成任何混亂。

希望這能回答您的問題。 我不介意投票,但請讓我知道為什么,這樣我們大家都可以學習。

不要忘記ORM\\Filter\\BetweenAware接口添加到Entity類,否則過濾器將被忽略。

我發現了另一種更簡單的方法。 好的,使用findBy不可能,但是我們可以使用createQueryBuilder ,請參見一個小例子:

$qb = $this->transactionMapper->createQueryBuilder('transaction');

$query = $qb->select('t')
            ->from('Transaction\Entity\Transaction', 't')
            ->where($qb->expr()->between('t.created', "'2014-02-01'", "'2014-03-01'"));

return $query->getQuery()->getResult();

查看文檔QueryBuilder

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM