Doctrine2中的间隔

时间:2013-11-15 14:49:36

标签: php doctrine-orm doctrine

我需要从数据库中获取实体,这些实体将在15分钟后更新。我试过这样的事情:

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

但这显然失败了,因为Doctrine不支持INTERVAL。

我在应用程序上有不同的时区&数据库服务器,所以我需要使用数据库日期函数,不能在PHP中使用new DateTime('-15 minutes')

1 个答案:

答案 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

的更多信息