2013-11-15 2 views
0

Мне нужно получить объекты из базы данных, которые обновляются через 15 минут. Я пробовал примерно следующее:Интервал в Doctrine2

$entityManager->createQuery(" 
    SELECT t FROM \Trip t 
    WHERE 
     t.dateUpdated > (CURRENT_TIMESTAMP() - INTERVAL ?1 MINUTES) 
"); 

Но это явно не получилось, потому что Doctrine не поддерживает INTERVAL.

У меня разные часовые пояса на сервере приложений &, поэтому мне нужно использовать функцию даты базы данных и не использовать new DateTime('-15 minutes') в PHP.

ответ

2

INTERVAL не поддерживается доктриной Lexter, потому что Doctrine была построена как можно более общая, чтобы она была совместима с множеством поставщиков баз данных.

В некоторых случаях это не идеально, потому что вы не можете использовать специфические для вендора функции (например, INTERVAL) в своем DQL, поэтому вам придется либо писать специфический для поставщика SQL, либо добавлять функцию, которую вы хотите использовать в Doctrine.

Вы можете зарегистрировать свои функции, добавив их в конфигурацию ОРМ в vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php в корневой каталог вашего веб Symfony:

<?php 
$config = new \Doctrine\ORM\Configuration(); 
$config->addCustomStringFunction($name, $class); 
$config->addCustomNumericFunction($name, $class); 
$config->addCustomDatetimeFunction($name, $class); 

$em = EntityManager::create($dbParams, $config); 

$name это имя функция будет называться в запросе DQL. $class - это строка имени класса, которая должна расширять Doctrine \ ORM \ Query \ Node \ FunctionNode. Это класс, который предлагает все необходимые API и методы для реализации пользовательской функции.

Вы можете найти конкретные примеры того, как это сделать here

Метод 2. Написание SQL

В некоторых случаях это просто проще писать SQL в Symfony, используя доктрину в PDO обертка этот путь:

$em = $this->getDoctrine()->getManager(); 
$query = "SELECT 1"; 
$stmt = $em->getConnection()->query($query); 
$results = $stmt->fetchAll(PDO::FETCH_ASSOC); 

или если ваш запрос параметризованных:

$foo = 1; 
$em = $this->getDoctrine()->getManager(); 
$query = "SELECT :foo"; 
$stmt = $em->getConnection()->prepare($query); 
$stmt->bindParam(':foo', $foo, PDO::PARAM_STR); 
$results = $stmt->fetchAll(PDO::FETCH_ASSOC); 

Кроме того, если вы не хотите вкладывать слишком много «жира» в свои контроллеры, вы можете создать пользовательский репозиторий в Symfony, чтобы ваш сложный DQL/SQL был отделен от вашей основной программы.

вы можете прочитать больше о пользовательских репозиториях here

+0

Спасибо, я использовал метод 1. и создали пользовательские функции. Второй метод возвращает только массивы, а не сущности, верно? –

+0

Правильно, он возвращает только массивы/объекты, но не возвращает объекты. Вы можете получить объекты после этого, если у вас есть идентификатор и использовать что-то вроде '$ this-> getDoctrine() -> getRepository ('yourBundle: yourEntity) -> find ($ result [' entityId ']); – ILikeTacos