Как я могу преобразовать обычный запрос SQL в доктрину ORM - PullRequest
0 голосов
/ 19 февраля 2019

Я только начал изучать Symfony 3.4 и Doctrine ORM.Мне нужно принять во внимание количество пользователей.Я проверил с нормальным запросом, он работает нормально.Как я могу преобразовать обычный запрос в Doctrine ORM?Любая помощь будет оценена.

"SELECT count(DATE_FORMAT(application.reviewed_at, '%Y-%m-%d')) AS count, user_id FROM application WHERE user_id = 6 AND DATE(reviewed_at) = CURDATE() GROUP BY DATE(reviewed_at)";

Я попробовал код ниже.Это не работает.

$qb      = $em->createQueryBuilder();
$entries = $qb->select("count(DATE_FORMAT(application.reviewed_at, '%Y-%m-%d')) AS count", "user_id")
            ->where("user_id = 6", "DATE(reviewed_at) = CURDATE()")
            ->from('AppBundle\Entity\Application', 'u');
            ->groupBy("DATE(reviewed_at)");
            ->getQuery()
            ->getResult();

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

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

Одна из причин, по которой ваш запрос не работал, - это попытка использовать собственный SQL (MySQL, чтобы быть правдой)функции внутри DQL-запроса.У DQL нет таких функций, и у вас есть 2 способа сделать это:

  1. Перепишите запрос так, чтобы он был совместим с Doctrine.Это может включать обновления для вашей схемы базы данных.В вашем конкретном случае вы можете захотеть преобразовать столбец reviewet_at из того, что он есть сейчас (timestamp я полагаю) в тип date, который позволяет проводить прямые сравнения дат.Это позволит вам избавиться от пользовательских функций преобразования даты MySQL и сделает ваш запрос совместимым с Doctrine
  2. . Вы можете выбрать более сложный путь и реализовать все необходимые пользовательские функции непосредственно в Doctrine.Это не простая вещь, но Доктрина достаточно гибка, чтобы предоставить вам такую ​​способность.Если вам будет интересно, в документацию Doctrine есть хорошая статья в документации по этой теме.
0 голосов
/ 19 февраля 2019

Попробуйте попробовать это:

public function select()
{
    $queryBuilder = $this->createQueryBuilder('a');

    $queryBuilder
        ->addSelect(['a.user_id', $queryBuilder->expr()->count('a.reviewed_at')])
        ->where('a.user_id = :idUser')
        ->andWhere('a.reviewed_at = :date')
        ->setParameters([
            'idUser' => 6,
            'date' => new \DateTime(),
        ])
        ->groupBy('a.reviewed_at')
    ;

    return $queryBuilder
        ->getQuery()
        ->getResult()
    ;
}
0 голосов
/ 19 февраля 2019

Проще говоря, Doctrine ORM не предназначен для преобразования запросов SQL обратно в DQL.DQL - это язык запросов, который может быть переведен в несколько вариантов SQL для конкретного поставщика, поэтому это одностороннее преобразование из DQL в SQL.

Таким образом, если у вас есть только запрос SQL, это может бытьхорошая идея использовать именно это, используя Doctrine DBAL .Конечно, вам, вероятно, придется иметь дело с отображениями наборов результатов, но может не потребоваться перетаскивать все содержимое ORM в ваш код.

То, что вы здесь делаете, - это, по сути, создание DQL-запроса с использованиемДоктрина QueryBuilder API.Часть FROM абсолютно верна, но те, которые используют функции DATE_FORMAT и DATE, выглядят неправильно для меня.Поскольку DQL переводится в несколько различных реализаций SQL, в зависимости от используемого вами драйвера, ему необходим уровень совместимости, поскольку такие функции, как DATE_FORMAT, DATE и CURDATE, не являются общими для всех платформ.

Сначала взгляните на документацию для пользовательских функций .Например, функция DATEDIFF() в MySQL является хорошим примером.Если окажется, что никто еще не реализовал поддержку функций, которые вы используете, это хорошее место для начала, так как он в основном описывает, как реализовать расширение для языка запросов Doctrine (DQL).

Во-вторых, есть хороший шанс, что используемые вами функции уже реализованы в некоторых сторонних библиотеках, таких как OroCRM или Расширения Doctrine Бенджамина Эберлей.

Кроме того, если вы выбираете агрегацию или результат вызова функции, всегда полезно псевдоним.Здесь вы можете попробовать использовать подмножество функций $qb->expr(), чтобы ограничить DQL более строгой грамматикой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...