在extbase查询中有没有办法使用mysql函数?

时间:2016-07-21 13:13:28

标签: php sql orm typo3 extbase

如果我想使用extbase模型查询(使用对象关系模型),我该怎么办。

SELECT uid FROM table WHERE fIND_IN_SET('4',column_name);

或类似

SELECT SUM(column_name) FROM table WHERE 1
  

注意:我不想使用statement()方法使用自定义查询

4 个答案:

答案 0 :(得分:1)

如果您指定了“不想”使用自定义语句的原因,您会发现自己错了。您的情况是statement()首先存在的确切原因。试图避免以几乎任何代价使用它是不合理的,因为extbase的SQL能力远远不能涵盖所有用例。总结一下:使用extbase API,其中逻辑和一个明显的好选择,但不要回避使用它是明显的最佳选择,因为它使用了extbase API“看起来更好”或者看起来像是你的API'重新“使用框架充分发挥其潜力”。

答案 1 :(得分:0)

截至目前,既没有FIND_IN_SET函数的等价函数,也没有聚合函数的等价函数。

您只能通过自定义语句或编写自己的TYPO3\CMS\Extbase\Persistence\Generic\Query类扩展来解决此问题。当然,您必须考虑使用自定义statement().时必须考虑的安全注意事项。但是,类扩展也会产生相同的安全隐患。

更具体地说明FIND_IN_SET函数:您不能只使用like()方法。例如,如果你正在搜索id 1,你会在一个由10,11,12,13等任何一个组成的集合中找到它。此外,由于like()方法只接受属性名称并且不允许在函数中包装列名称,因此无法解决该问题。

答案 2 :(得分:-1)

根据你的问题:我不认为在不使用wendy_form['altZip'] = '10013'的情况下有任何方法可以在extbase中使用mysql函数。

根据您的示例:您可以尝试statement()

答案 3 :(得分:-1)

这是可能的,但需要一点努力。我在我的新闻扩展中已经这样做了。代码看起来像那样

    $query = // your $query->execute();

    $queryParser = $this->objectManager->get(Typo3DbQueryParser::class);
    list($hash, $parameters) = $queryParser->preparseQuery($query);
    $statementParts = $queryParser->parseQuery($query);

    // Limit and offset are not cached to allow caching of pagebrowser queries.
    $statementParts['limit'] = ((int)$query->getLimit() ?: null);
    $statementParts['offset'] = ((int)$query->getOffset() ?: null);

    $tableNameForEscape = (reset($statementParts['tables']) ?: 'foo');
    foreach ($parameters as $parameterPlaceholder => $parameter) {
        if ($parameter instanceof LazyLoadingProxy) {
            $parameter = $parameter->_loadRealInstance();
        }

        if ($parameter instanceof \DateTime) {
            $parameter = $parameter->format('U');
        } elseif ($parameter instanceof DomainObjectInterface) {
            $parameter = (int)$parameter->getUid();
        } elseif (is_array($parameter)) {
            $subParameters = [];
            foreach ($parameter as $subParameter) {
                $subParameters[] = $GLOBALS['TYPO3_DB']->fullQuoteStr($subParameter, $tableNameForEscape);
            }
            $parameter = implode(',', $subParameters);
        } elseif ($parameter === null) {
            $parameter = 'NULL';
        } elseif (is_bool($parameter)) {
            return ($parameter === true ? 1 : 0);
        } else {
            $parameter = $GLOBALS['TYPO3_DB']->fullQuoteStr((string)$parameter, $tableNameForEscape);
        }

        $statementParts['where'] = str_replace($parameterPlaceholder, $parameter, $statementParts['where']);
    }

    $statementParts = [
        'selectFields' => implode(' ', $statementParts['keywords']) . ' ' . implode(',', $statementParts['fields']),
        'fromTable' => implode(' ', $statementParts['tables']) . ' ' . implode(' ', $statementParts['unions']),
        'whereClause' => (!empty($statementParts['where']) ? implode('', $statementParts['where']) : '1')
            . (!empty($statementParts['additionalWhereClause'])
                ? ' AND ' . implode(' AND ', $statementParts['additionalWhereClause'])
                : ''
            ),
        'orderBy' => (!empty($statementParts['orderings']) ? implode(', ', $statementParts['orderings']) : ''),
        'limit' => ($statementParts['offset'] ? $statementParts['offset'] . ', ' : '')
            . ($statementParts['limit'] ? $statementParts['limit'] : '')
    ];

    $sql = $GLOBALS['TYPO3_DB']->SELECTquery(
        $statementParts['selectFields'],
        $statementParts['fromTable'],
        $statementParts['whereClause'],
        '',
        $statementParts['orderBy'],
        $statementParts['limit']
    );

    return $sql;

通过使用DataMapper,您可以将原始结果映射回模型,如果您也需要。该代码看起来像那样

$dataMapper = $objectManager->get(DataMapper::class);
$records = $dataMapper->map($className, $rows);