我需要从数据库中获取实体,这些实体将在15分钟后更新。我试过这样的事情:
$entityManager->createQuery("
SELECT t FROM \Trip t
WHERE
t.dateUpdated > (CURRENT_TIMESTAMP() - INTERVAL ?1 MINUTES)
");
但这显然失败了,因为Doctrine不支持INTERVAL。
我在应用程序上有不同的时区&数据库服务器,所以我需要使用数据库日期函数,不能在PHP中使用new DateTime('-15 minutes')
。
答案 0 :(得分:2)
Doctrine Lexter不支持INTERVAL,因为Doctrine的构建尽可能通用,因此它可以与许多数据库供应商兼容。
在某些情况下,这并不理想,因为您无法在DQL中使用特定于供应商的功能(如INTERVAL),因此您必须编写特定于供应商的SQL或将所需的功能添加到Doctrine中。
您可以注册函数,将它们添加到Symfony Web根目录中vendor/doctrine/orm/lib/Doctrine/ORM/Configuration.php
的ORM配置中:
<?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
在某些情况下,使用Doctrine的PDO包装器以这种方式在Symfony中编写SQL更容易:
$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
的更多信息