Symfony2 datetime queryBuilder
У меня есть 2 DateTime классы в проекте Symfony2. У меня есть entity Stat, у которого есть свойство $date.
/**
* @ORM\Column(type="date", length="11")
*/
protected $date;
Мне нужно делать запросы, используя DateTime объекты в createQueryBuilder. Как я могу это сделать? Например:
$date_from = new DateTime('2012-02-01');
$date_to = new DateTime('2012-02-15');
Мне нужно получить все строки из таблицы статистики (entity Stat) между $date_from и $date_to. Как написать мой запрос с помощью createQueryBuilder? Мой текущий код:
$qb = $em->createQueryBuilder();
$query = $qb->select('s')
->from('ACME\MyBundle\Entity\Stat', 's')
->where('s.date >= :date_from')
->andWhere('s.date <= :date_to')
->setParameter('date_from', $date_from)
->setParameter('date_to', $date_to)
->getQuery();
Ответы
Ответ 1
Бенджамин отвечает правильно, но ему не хватает одной детали.
Это правильный способ сделать это:
$qb->andWhere($qb->expr()->between('s.date', ':date_from', ':date_to'));
Но для установки параметров мне нужно сделать вот так:
$qb->setParameter('date_from', $date_from, \Doctrine\DBAL\Types\Type::DATETIME);
$qb->setParameter('date_to', $date_to, \Doctrine\DBAL\Types\Type::DATETIME);
Если я опускаю типы DATETIME, я получаю следующую ошибку (см. здесь):
Объект класса DateTime не может быть преобразован в строку
Я использую Doctrine DBAL 2.0.5, это поведение, возможно, изменилось в более поздних версиях Doctrine.
Ответ 2
QueryBuilder - хорошее решение.
Но вы можете использовать
->andWhere($qb->expr()->between('s.date', ':date_from', 'date_to'))
или
->andWhere($qb->expr()->andX(array(
$qb->expr()->gte('s.date', ':date_from'),
$qb->expr()->lte('s.date', ':date_to'))
)
$qb- > expr() → andX полезен, если вы не хотите иметь некоторую WTF, когда вы добавляете некоторые из них и где угодно или где угодно.
Здесь у вас есть документация doctrine2 для queryBuilder
Вы также можете использовать метод setParameters для своих параметров
->setParameters(array(
'date_from' => $date_from,
'date_to' => $date_to,
))
Ответ 3
У меня была аналогичная ситуация. Я не мог использовать → setParameter из-за того, как был создан мой код, поэтому я помещал эту переменную $andX в "улавливать" все условия, созданные в цикле foreach (в этом случае я просто написал одно с датами, потому что другие не имеет значения прямо сейчас).
$this->qb = $this->em->createQueryBuilder();
$andX = $this->qb->expr()->andX();
$this->qb->select('u')
->from('models\User','u');
foreach($data as $key=>&$value){
if($key == 'date'){
$from = $this->qb->expr()->gte('u.date_from',$this->qb->expr()->literal($value['datefrom']));
$to = $this->qb->expr()->lte('u.date_to',$this->qb->expr()->literal($value['dateto']));
$condition = $from. ' AND ' .$to;
$andX->add($condition);
}
//other if
}
Обратите внимание, что параметр для этой функции является многомерным массивом. Надеюсь, что это будет полезно.