[英]INET_ATON in where statement doctrine2 querybuilder zend2
问题:我想在Doctrine2中使用querybuilder运行查询,例如:
SELECT * FROM TABLE WHERE `column1` = 'x' and (`column2` = INET_ATON('1.1.1.1') OR `column3` like '%bla%'...)
我该如何在Zend2中使用Doctrine2?
我尝试了这个:
$where->add($qb->expr()->eq('column2', $qb->expr()->literal('inet_aton('1.1.1.1'))));
但这不起作用。 原则仍然在inet_aton函数周围添加引号。
好吧,我自己弄清楚了:
您应该做的几件事:
首先做一个DQL功能
<?php
namespace Application\DQL;
use Doctrine\ORM\Query\Lexer;
class InetAtonFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
{
public $valueExpression = null;
/**
* parse
*
* @param \Doctrine\ORM\Query\Parser $parser
* @access public
* @return void
*/
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->valueExpression = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
/**
* getSql
*
* @param \Doctrine\ORM\Query\SqlWalker $sqlWalker
* @access public
* @return string
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $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', 'Application\DQL\InetAtonFunction');
}
...
在此之后,您就可以开始了。 现在,您可以使用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: home\myBundle\myFolderContaintClass\InetAton
这是解释在这里正式的Symfony文档上。
这个问题似乎是等同于ROUND()的Doctrine 2 DQL MySQL的副本吗?
您需要为此实现一个自定义DQL函数 。
DoctrineExtensions中有一些示例。
您可以像下面这样实现:
<?php
namespace MyApp\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\SqlWalker;
class InetAnon extends FunctionNode
{
private $arithmeticExpression;
public function getSql(SqlWalker $sqlWalker)
{
return 'INET_ANON(' . $sqlWalker->walkSimpleArithmeticExpression(
$this->arithmeticExpression
) . ')';
}
public function parse(\Doctrine\ORM\Query\Parser $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 \Doctrine\ORM\Configuration();
$config->addCustomNumericFunction('INET_ANON', 'MyApp\DQL\InetAnon');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.