Extbase TYPO3 - 使用自定义 WHERE 部分扩展查询

问题描述 投票:0回答:1

我有一个模型(“优惠”),它具有 lat/lng 属性以及许多其他元属性。在存储库方法中,我可以根据匹配的元数据获取报价,例如:

$where[] = $query->equals('special', 1);
$where[] = $query->equals('region', 7);
$where[] = $query->greaterThan('crdate', $minTime);

现在我需要能够根据纬度/经度属性进行半径搜索。在通常的 SQL 查询中,这将类似于:

WHERE acos(sin(:lat)*sin(radians(lat)) + cos(:lat)*cos(radians(lat))*cos(radians(lng)-:lng)) * :R < :rad

但是,由于这包含数学值,我看不到添加 $query 对应项的可能性。我如何将这样的 WHERE 部分传递给 extbase 查询?

我想避免的:

  • 使用原始 admin_query() 和 $GLOBALS['TYPO3_DB'] 以及我在正确查询的execute()方法之前收集的所有相同的$where条件,收集可用记录的UID,并附加$查询的条件仅返回与第二个查询的 UID 匹配的内容

  • 重写整个存储库方法以使用原始 sql 方法并迭代该方法以生成 Extbase 的属性 ER 模型。

所以理想情况下,我想要这样的东西:

$query->customSQL('blablabla > bla');

稍后将附加到 SQL WHERE 部分。也许我可以先创建一个占位符,比如

$query->equals('placeholder', 1);

然后以某种方式在执行前获取语句,执行 a

str_replace('placeholder = 1', '...我的真实半径语句...')

但我在 QueryInterface 中只看到 getStatement() 而不是 setStatement()...

php mysql typo3 extbase typo3-7.6.x
1个回答
0
投票

您要查找的函数称为

\TYPO3\CMS\Extbase\Persistence\Generic\Query()
,它没有在界面中定义。您必须自己编写整个查询 - 在这里不可能混合 extbase 查询生成器和纯 SQL 代码。

不过,您可以(并且应该)在此处使用准备好的查询 (

\TYPO3\CMS\Core\Database\PreparedStatement
)。

我在项目中做了类似的事情并将我的代码粘贴在下面,也许对你有帮助:

/**
 * Creates a prepared statement
 *
 * @return \TYPO3\CMS\Core\Database\PreparedStatement
 */
protected function getPreparedStatement()
{
    if (is_null($this->statement)) {
        $this->statement = $this->getDatabaseConnection()->prepare_SELECTquery(
            '*, ( :meanradius * acos(LEAST(1, cos( radians( :latitude ) ) * cos( radians( latitude ) )' .
            ' * cos( radians( longitude ) - radians( :longitude ) )' .
            ' + sin( radians( :latitude ) ) * sin( radians( latitude ) ) ) )' .
            ' ) AS distance',
            $this->tableName,
            'HAVING distance < :radius',
            '',
            'distance',
            ':limit '
        );
    }
    return $this->statement;
}

然后,在我的

find*
方法中:

    $query = $this->createQuery();
    $statement = $this->getPreparedStatement();
    $statement->bindValues([
        ':meanradius' => CoordinateInterface::EARTH_MEAN_RADIUS,
        ':latitude' => $latitude,
        ':longitude' => $longitude,
        ':radius' => $radius,
        ':limit' => $limit,
    ]);
    $query->statement(($statement));
    return $query->execute();
© www.soinside.com 2019 - 2024. All rights reserved.