本文概述
Doctrine 2的DQL解析器具有钩子来注册可以在DQL查询中使用并转换为SQL的函数, 从而允许扩展Doctrines Query功能, 而不必编写原始SQL。在本文中, 我们将向你简要介绍如何在Symfony 4项目上配置自定义原则扩展。
1.创建/选择你的DQL扩展
第一步, 在Symfony项目的src目录中创建一个目录, 即DQL。此目录将存储你要注册为自定义学说扩展的类。在此目录中, 存储在其中的文件的名称空间应为App \ DQL。在我们的例子中, 我们要注册2个自定义文本扩展名的教义(匹配和soundex), 所以我们将有2个文件, 我们的结构如下所示:
我们将注册的MatchAgainst函数和文件MatchAgainst.php的代码如下(对你来说, 只有名称空间很重要):
namespace App\DQL;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
/**
* "MATCH_AGAINST" "(" {StateFieldPathExpression ", "}* InParameter {Literal}? ")"
*/
class MatchAgainst extends FunctionNode {
public $columns = array();
public $needle;
public $mode;
public function parse(\Doctrine\ORM\Query\Parser $parser) {
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
do {
$this->columns[] = $parser->StateFieldPathExpression();
$parser->match(Lexer::T_COMMA);
} while ($parser->getLexer()->isNextToken(Lexer::T_IDENTIFIER));
$this->needle = $parser->InParameter();
while ($parser->getLexer()->isNextToken(Lexer::T_STRING)) {
$this->mode = $parser->Literal();
}
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) {
$haystack = null;
$first = true;
foreach ($this->columns as $column) {
$first ? $first = false : $haystack .= ', ';
$haystack .= $column->dispatch($sqlWalker);
}
$query = "MATCH(" . $haystack .
") AGAINST (" . $this->needle->dispatch($sqlWalker);
if ($this->mode) {
$query .= " " . $this->mode->dispatch($sqlWalker) . " )";
} else {
$query .= " )";
}
return $query;
}
}
拥有有效的扩展名后, 请继续进行下一步注册。
2.注册DQL扩展名
要在Symfony 4中注册DQL函数, 只需在原则中的orm的dql块下指定相应类中的类来注册它们。请记住, 在Doctrine中, DQL中只有三种类型的函数:返回数字值的函数, 返回字符串的函数和返回Date的函数, 因此必须有一个包含每种函数类型的主要块:
# config/packages/doctrine.yaml
doctrine:
orm:
# ...
dql:
string_functions:
test_string: App\DQL\StringFunction
second_string: App\DQL\SecondStringFunction
numeric_functions:
test_numeric: App\DQL\NumericFunction
datetime_functions:
test_datetime: App\DQL\DatetimeFunction
在我们的例子中, 使用我们的MatchAgainst和Soundex函数来处理文本, 我们只需在string_functions节点下的doctrine.yaml文件中向以下代码段注册它们即可:
# app/config/packages/doctrine.yaml
doctrine:
# Under orm, create the DQL
orm:
#
# ...
#
dql:
# Register string functions with the correct namespace
string_functions:
MATCH_AGAINST: App\DQL\MatchAgainst
SOUNDEX: App\DQL\SoundexFunction
对于明确声明的实体经理
如果在Doctrine中使用多个实体管理器, 则可以在管理器块中专门为其中一些注册自定义函数:
# config/packages/doctrine.yaml
doctrine:
orm:
# ...
entity_managers:
example_manager:
dql:
string_functions:
MATCH_AGAINST: App\DQL\MatchAgainst
编码愉快!
评论前必须登录!
注册