Doctrine orm 使用本机SQL查询的原则DTO
我目前有一个相当复杂的本机SQL查询,用于报告目的。考虑到它处理的数据量,这是使用本机SQL处理数据的唯一有效方法 这可以很好地工作,并从标量结果返回一个数组数组 我想做的是,使用数据传输对象(DTO),以使结果与项目中的所有其他结果集保持一致。返回简单DTO对象的数组Doctrine orm 使用本机SQL查询的原则DTO,doctrine-orm,dto,Doctrine Orm,Dto,我目前有一个相当复杂的本机SQL查询,用于报告目的。考虑到它处理的数据量,这是使用本机SQL处理数据的唯一有效方法 这可以很好地工作,并从标量结果返回一个数组数组 我想做的是,使用数据传输对象(DTO),以使结果与项目中的所有其他结果集保持一致。返回简单DTO对象的数组 这些在DQL中工作得很好,但我看不出在原生SQL中使用它们。这可能吗?原则可以将原始SQL查询的结果映射到实体,如下所示: 除非您也愿意使用DQL,否则我看不到对DTO的支持,因此不存在直接解决方案。我尝试了一个简单的变通方法
这些在DQL中工作得很好,但我看不出在原生SQL中使用它们。这可能吗?原则可以将原始SQL查询的结果映射到实体,如下所示: 除非您也愿意使用DQL,否则我看不到对DTO的支持,因此不存在直接解决方案。我尝试了一个简单的变通方法,效果很好,下面是实现目标的DQL和非DQL方法 这些例子是使用拉雷维尔和拉雷维尔学说扩展构建的
<?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;
}
}
<?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;
}
}
我不会过快地忽略DQL,因为它可以执行大多数类型的SQL。然而,我最近也参与了构建管理报告,在管理信息领域,SQL查询可以与整个PHP文件一样大。在这种情况下,我会加入你们的行列,放弃教条(或任何其他ORM)。伟大而详细的解决方案,我非常喜欢。我只是好奇,当有复杂的DTO或者我应该说是嵌套的DTO时,如何进行DTO转换。例如,具有标量和对象字段或对象列表的父DTO我在尝试使DTO家族化时遇到的问题是,您最终复制了许多条令本可以为您做的事情,结果是一团糟。如果涉及到非平凡的关系,我会考虑在正常的查询中运行本地查询。例如,您有一个简单的结果表,其中有一列或两列包含聚合。使用原始查询获取聚合,并通过主结果集的ID对其进行键控。然后只需查找每一行的统计数据。好处:能够遍历条令管理的关系,并一次性获得所有聚合。
<?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;
}
}
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;
}