gpt4 book ai didi

doctrine-orm - 带有原生 SQL 查询的 Doctrine DTO

转载 作者:行者123 更新时间:2023-12-03 23:47:51 26 4
gpt4 key购买 nike

我目前有一个相当复杂的 native SQL 查询,用于报告目的。鉴于它处理的数据量,这是处理它的唯一有效方法是使用 native SQL。

这工作正常,并从标量结果返回一个数组数组。

为了使结果与项目中的所有其他结果集保持一致,我想做的是使用数据传输对象 (DTO)。返回简单 DTO 对象的数组。

这些与 DQL 一起工作得非常好,但无论如何我都看不到将它们与 native SQL 一起使用。这是可能吗?

最佳答案

Doctrine 可以将原始 SQL 查询的结果映射到实体,如下所示:

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/native-sql.html

除非您也愿意使用 DQL,否则我看不到对 DTO 的支持,因此不存在直接解决方案。我尝试了一个效果很好的简单解决方法,所以这里有 DQL 和非 DQL 方法来实现您的目标。

这些示例是使用 Laravel 和 Laravel Doctrine 扩展构建的。

  • DTO

  • 下面的 DTO 支持 DQL 绑定(bind)和自定义映射,因此构造函数必须能够使用和不使用参数。
    <?php namespace App\Dto;

    /**
    * Date with corresponding statistics for the date.
    */
    class DateTotal
    {
    public $taskLogDate;
    public $totalHours;

    /**
    * DateTotal constructor.
    *
    * @param $taskLogDate The date for which to return totals
    * @param $totalHours The total hours worked on the given date
    */
    public function __construct($taskLogDate = null, $totalHours = null)
    {
    $this->taskLogDate = $taskLogDate;
    $this->totalHours = $totalHours;
    }

    }
  • 使用 DQL 获取结果

  • 这是使用 DQL 的标准版本。
    public function findRecentDateTotals($taskId)
    {
    $fromDate = new DateTime('6 days ago');
    $fromDate->setTime(0, 0, 0);
    $queryBuilder = $this->getQueryBuilder();

    $queryBuilder->select('NEW App\Dto\DateTotal(taskLog.taskLogDate, SUM(taskLog.taskLogHours))')
    ->from('App\Entities\TaskLog', 'taskLog')
    ->where($queryBuilder->expr()->orX(
    $queryBuilder->expr()->eq('taskLog.taskLogTask', ':taskId'),
    $queryBuilder->expr()->eq(0, ':taskId')
    ))
    ->andWhere(
    $queryBuilder->expr()->gt('taskLog.taskLogDate', ':fromDate')
    )
    ->groupBy('taskLog.taskLogDate')
    ->orderBy('taskLog.taskLogDate', 'DESC')
    ->setParameter(':fromDate', $fromDate)
    ->setParameter(':taskId', $taskId);

    $result = $queryBuilder->getQuery()->getResult();
    return $result;
    }
  • 支持带有 native SQL 的 DTO

  • 这是一个简单的助手,可以将原始 SQL 查询的数组结果编码为对象。它也可以扩展到做其他事情,也许是自定义更新等等。
    <?php namespace App\Dto;

    use Doctrine\ORM\EntityManager;

    /**
    * Helper class to run raw SQL.
    *
    * @package App\Dto
    */
    class RawSql
    {
    /**
    * Run a raw SQL query.
    *
    * @param string $sql The raw SQL
    * @param array $parameters Array of parameter names mapped to values
    * @param string $className The class to pack the results into
    * @return Object[] Array of objects mapped from the array results
    * @throws \Doctrine\DBAL\DBALException
    */
    public static function query($sql, $parameters, $className)
    {
    /** @var EntityManager $em */
    $em = app('em');
    $statement = $em->getConnection()->prepare($sql);
    $statement->execute($parameters);
    $results = $statement->fetchAll();

    $return = array();
    foreach ($results as $result) {
    $resultObject = new $className();
    foreach ($result as $key => $value) {
    $resultObject->$key = $value;
    }
    $return[] = $resultObject;
    }
    return $return;
    }
    }
  • 运行原始 SQL 版本

  • 该函数的使用和调用方式与其他存储库方法相同,只需调用上述帮助程序即可自动将数据转换为对象。
    public function findRecentDateTotals2($taskId)
    {
    $fromDate = new DateTime('6 days ago');

    $sql = "
    SELECT
    task_log.task_log_date AS taskLogDate,
    SUM(task_log.task_log_hours) AS totalHours
    FROM task_log task_log
    WHERE (task_log.task_log_task = :taskId OR :taskId = 0) AND task_log.task_log_date > :fromDate
    GROUP BY task_log_date
    ORDER BY task_log_date DESC
    ";

    $return = RawSql::query(
    $sql,
    array(
    'taskId' => $taskId,
    'fromDate' => $fromDate->format('Y-m-d')
    ),
    DateTotal::class
    );
    return $return;
    }
  • 备注

  • 我不会太快放弃 DQL,因为它可以执行大多数类型的 SQL。然而,我最近也参与了构建管理报告的工作,在管理信息领域,SQL 查询可以与整个 PHP 文件一样大。在那种情况下,我也会加入你并放弃 Doctrine(或任何其他 ORM)。

    关于doctrine-orm - 带有原生 SQL 查询的 Doctrine DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34930702/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com