Сравните два поля базы данных в репозитории extbase - PullRequest
0 голосов
/ 07 марта 2019

Я использую TYPO3 8. В моем расширении у меня есть таблица базы данных «company», в которой я храню для каждой компании общее количество мест (number_places) и количество занятых мест (busy_places). Теперь я хочу ограничить поиск компаниями, у которых есть свободные места. В MySQL это будет выглядеть так:

SELECT * FROM company WHERE number_places > occupied_places;

Как мне создать этот запрос в репозитории extbase?

Я пытался ввести в моей модели виртуальное свойство placeLeft, но оно не сработало.

Я не хочу использовать необработанный оператор SQL, как упомянуто ниже, потому что я уже реализовал фильтр, который использует множество различных ограничений.

Запрос Extbase для сравнения двух полей в одной таблице

Ответы [ 2 ]

1 голос
/ 09 марта 2019

Вы можете сделать это так в своем классе репозитория, пожалуйста, обратите внимание на комментарии внутри кода:

class CompanyRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
    public function findWithAvailablePlaces(bool $returnRawQueryResult = false)
    {
        // Create a QueryBuilder instance
        $queryBuilder = $this->objectManager->get(\TYPO3\CMS\Core\Database\ConnectionPool::class)
            ->getConnectionForTable('company')->createQueryBuilder();

        // Create the query
        $queryBuilder
            ->select('*')
            ->from('company')
            ->where(
                // Note: this string concatenation is needed, because TYPO3's
                // QueryBuilder always escapes the value in the ExpressionBuilder's
                // methods (eq(), lt(), gt(), ...) and thus render it impossible to
                // compare against an identifier.
                $queryBuilder->quoteIdentifier('number_places')
                . \TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder::GT
                . $queryBuilder->quoteIdentifier('occupied_places')
            );

        // Execute the query
        $result = $queryBuilder->execute()->fetchAll();

        // Note: this switch is not needed in fact. I just put it here, if you
        // like to get the Company model objects instead of an array.
        if ($returnRawQueryResult) {
            $dataMapper = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
            return $dataMapper->map($this->objectType, $result);
        }
        return $result;
    }
}

Примечания:

  • Если вам нужно иметь дело с большим количеством записей, я бы - по соображениям производительности - не использовал функцию отображения данных и не работал с массивами.

  • Если вы хотите использовать жидкий виджет нумерации страниц, убедитесь, что вы не используете его, и создайте свою собственную нумерацию страниц. Из-за того, как это работает (extbase-inside), вы получите огромную нагрузку на систему при увеличении таблицы. Лучше добавить поддержку ограниченных запросов к базе данных в метод репозитория, например:

class CompanyRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
    public function findWithAvailablePlaces(
        int $limit = 10,
        int $offset = 0,
        bool $returnRawQueryResult = false
    ) {
        // ...
        $queryBuilder
            ->setMaxResults($limit)
            ->setFirstResult($offset);
        $result = $queryBuilder->execute()->fetchAll();
        // ...
    }
}
1 голос
/ 07 марта 2019

Я думаю, что вы не можете сделать это, используя стандартные методы Extbase Query, такие как equals () и так далее.Вы можете использовать функцию $query->statement() для ваших конкретных запросов, подобных этой.Вы также можете использовать QueryBuilder начиная с TYPO3 8, в котором есть функции для сравнения полей друг с другом: https://docs.typo3.org/typo3cms/CoreApiReference/latest/ApiOverview/Database/QueryBuilder/Index.html#quoteidentifier-and-quoteidentifiers Хорошо использовать этот QueryBuilder в репозиториях Extbase.После этого вы можете использовать DataMapper для сопоставления результатов запроса с моделями Extbase.

В случае использования «Statement ()» помните об экранировании каждого значения, которое может вызвать любые SQL-инъекции.

...