2013-03-25 72 views
2

问:我想在Doctrine2运行与QueryBuilder的查询,如:INET_ATON在声明中doctrine2的QueryBuilder zend2

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')))); 

但是doen't工作。 Doctrine还在inet_aton函数中添加了引号。

+0

这是否有帮助 - > https://groups.google.com/forum/?fromgroups=#!topic/doctrine-user/gdCG5MoByD4 – Crisp 2013-03-25 16:04:19

+0

可能的重复http://stackoverflow.com/questions/15623257/doctrine- 2- DQL MySQL的当量至圆 – Ocramius 2013-03-26 06:07:58

回答

3

好吧,我想通了自己:

你应该做的几件事:

首先做一个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) . ')'; 
    } 
} 

后,该功能添加到学说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(:?) 

我希望这可以帮助其他人在学说和Zend Framework2

1

这个问题似乎是Doctrine 2 DQL MySQL equivalent to ROUND()?

重复你需要实现一个custom DQL function

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'); 
1

只是一个答案的特殊功能进行更新:(对于新的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文档中的here的解释。