【问题标题】:Is there any way to use mysql function in extbase querying?有没有办法在 extbase 查询中使用 mysql 函数?
【发布时间】:2016-07-21 13:13:27
【问题描述】:

如果我想使用 extbase 模型查询(使用对象关系模型)进行以下操作,我该怎么办。

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

或者类似的东西

SELECT SUM(column_name) FROM table WHERE 1

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

【问题讨论】:

    标签: php sql orm typo3 extbase


    【解决方案1】:

    如果您指定了为什么不“想要”使用自定义语句,您会意识到您错了。您的情况是 statement() 首先存在的确切原因。几乎不惜一切代价试图避免使用它是不合理的,因为 extbase 的 SQL 能力远不能涵盖所有用例。总而言之:使用 extbase API 是合乎逻辑且明显的好选择,但不要回避 statement() 使用它的地方是明显的最佳选择,因为使用 extbase API“看起来更好”或者看起来像你的 API'重新“充分利用框架的潜力”。

    【讨论】:

      【解决方案2】:

      到目前为止,FIND_IN_SET 函数和聚合函数都没有等效项。

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

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

      【讨论】:

        【解决方案3】:

        根据您的问题:我认为没有任何方法可以在不使用statement() 的情况下在extbase 中使用mysql 函数。

        根据你的例子:你可以试试$query->like('columnName', "%{4}%")

        【讨论】:

        • 它会带来与find_in_set不同的结果,反正也不是SQL函数。
        • column_name 是什么类型?有什么不同的结果?能举个例子吗?
        • 这和区别没有关系,问题只是关于如何在查询中使用SQL函数。我举了 find_in_set 的例子,你可以考虑任何 SQL 函数。
        • 看,我已经更新了我的问题,使其更准确。 @jay dinse
        • 我明白了。据我所知,我认为没有statement() 就无法做到这一点。 extbase 中的查询函数调色板非常小,这迫使我比预期更频繁地使用statement()。尤其是没有join()-function 让我抓狂。
        【解决方案4】:

        这是可能的,但需要一些努力。我在我的新闻扩展中做到了这一点。代码是这样的

            $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); 
        

        【讨论】:

          猜你喜欢
          • 2011-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多