问题:我想在Doctrine2中使用querybuilder运行查询,如:
SELECT * FROM TABLE WHERE `column1` = 'x' and (`column2` = INET_ATON('1.1.1.1') OR `column3` like '%bla%'...)
我该如何在Doctrine2中使用Zend2?
我试过了:
$where->add($qb->expr()->eq('column2', $qb->expr()->literal('inet_aton('1.1.1.1'))));
但这不起作用。Doctrine仍然在inet_aton函数周围添加引号。
好吧,我自己弄明白了:
你应该做的几件事:
首先创建一个DQL函数
<?php
namespace ApplicationDQL;
use DoctrineORMQueryLexer;
class InetAtonFunction extends DoctrineORMQueryASTFunctionsFunctionNode
{
public $valueExpression = null;
/**
* parse
*
* @param DoctrineORMQueryParser $parser
* @access public
* @return void
*/
public function parse(DoctrineORMQueryParser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->valueExpression = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
/**
* getSql
*
* @param DoctrineORMQuerySqlWalker $sqlWalker
* @access public
* @return string
*/
public function getSql(DoctrineORMQuerySqlWalker $sqlWalker)
{
return 'INET_ATON('. $this->valueExpression->dispatch($sqlWalker) . ')';
}
}
之后将函数添加到Doctrine ORM
<?php
namespace Observer;
//...
class Module implements
AutoloaderProviderInterface,
ConfigProviderInterface,
ServiceProviderInterface
{
//...
public function onBootstrap($e)
{
$application = $e->getParam('application');
$sm = $application->getServiceManager();
$em = $application->getEventManager();
$entityManager = $sm->get('doctrine.entitymanager.orm_default');
$entityManager->getConfiguration()->addCustomStringFunction('inet_aton', 'ApplicationDQLInetAtonFunction');
}
...
这之后你就可以走了。现在您可以使用querybuilder运行查询,如
SELECT whatever FROM someting where cloumn = inet_aton(:?)
我希望这有助于其他人在Doctrine和Zend Framework2中的特殊功能
只是一个更新的答案:(对于新的SF版本)
创建DQL函数(参见旧文章)后,
我们想在Yaml (config.yml)中注册自定义DQL类,如下所示:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
dql:
string_functions:
inet_aton: homemyBundlemyFolderContaintClassInetAton
这在Symfony官方文档中有解释
这个问题似乎是Doctrine 2的重复DQL MySQL相当于ROUND()?
您需要为此实现一个自定义DQL函数。
在DoctrineExtensions中有一些例子。
你可以这样实现它:
<?php
namespace MyAppDQL;
use DoctrineORMQueryASTFunctionsFunctionNode;
use DoctrineORMQueryLexer;
use DoctrineORMQuerySqlWalker;
class InetAnon extends FunctionNode
{
private $arithmeticExpression;
public function getSql(SqlWalker $sqlWalker)
{
return 'INET_ANON(' . $sqlWalker->walkSimpleArithmeticExpression(
$this->arithmeticExpression
) . ')';
}
public function parse(DoctrineORMQueryParser $parser)
{
$lexer = $parser->getLexer();
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->arithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
你可以在引导ORM时在配置中注册它:
$config = new DoctrineORMConfiguration();
$config->addCustomNumericFunction('INET_ANON', 'MyAppDQLInetAnon');