我有一个模型(“商品”),其中包含许多其他元属性中的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对应项的可能性。我如何将这样的WHERE部分传递给extbase查询?
我想避免的事情:
使用带有$ GLOBALS ['TYPO3_DB']的原始admin_query()和所有相同的$ where条件,我在正确的Query的execute()方法之前收集条件,以收集可用记录的UID,并使用仅返回与第二个查询的UID相匹配的条件附加$ query
重写整个存储库方法以使用原始sql方法并对其进行迭代以生成Extbase的ER-Model。
理想情况下,我希望有类似的东西:
$query->customSQL('blablabla > bla');
稍后将附加到SQL WHERE部分。也许我可以先创建一个像
这样的占位符$query->equals('placeholder', 1);
然后在执行之前以某种方式获取语句,执行
str_replace('placeholder = 1','...我的真实半径声明......')
但我只在QueryInterface中看到getStatement()而不是setStatement()......
答案 0 :(得分: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();