extbase typo3-通过自定义零件扩展查询



i有一个模型(" usving"),该模型(" usve")在许多其他元属性中都具有LAT/LNG的属性。在一个存储库方法中,我可以根据匹配的元数据来获取提供:

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

现在,我需要能够根据LAT/LNG属性进行半径搜索。在通常的SQL查询中,这将是:

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

但是,由于它包含数学值,因此我认为添加$ QUERY对应物的可能性没有。我如何将像这样的部分传递到extbase查询?

我想避免的是:

  • 使用$ globals ['typo3_db']的RAW Admin_query(),所有与我在正确查询的execute()方法中收集的条件的所有相同$,以收集可用记录的UID,并以$查询为条件,该条件仅返回与第二个查询的UID匹配的条件

  • 重写整个存储库方法以使用RAW SQL方法,并迭代生成extbase的Propery ER模型。

非常理想的是,我想拥有类似的东西:

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

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

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

然后以某种方式在执行前获得声明,请做

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

,但我只看到getStatement()而不是queryInterface中的setstatement()...

您要查找的功能称为 TYPO3CMSExtbasePersistenceGenericQuery(),在接口中未定义。您必须自己编写整个查询 - 在此处不可能混合extbase查询构建器和普通SQL代码。

但是,您可以(并且应该)在这里使用准备好的查询(TYPO3CMSCoreDatabasePreparedStatement)。

我在项目中做了类似的事情,并在下面粘贴了我的代码,也许它可以帮助您:

/**
 * Creates a prepared statement
 *
 * @return TYPO3CMSCoreDatabasePreparedStatement
 */
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();

最新更新