使用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方法吗?
答案 0 :(得分:2)
简而言之,没有。 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类,否则将忽略过滤器。
答案 1 :(得分:2)
我发现了另一种更简单的方法。
好的,使用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();
请参阅文档The QueryBuilder