INET_ATON 在where 语句doctrine2 querybuilder zend2

问题描述 投票:0回答:4

问题:我想在 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'))));

但这行不通。 Doctrine 仍然在 inet_aton 函数周围添加引号。

php mysql doctrine-orm doctrine zend-framework2
4个回答
4
投票

好吧,我自己想出来了:

您应该做的几件事:

首先制作一个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 中具有特殊功能的人


2
投票

只是更新的答案:(对于新的 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的解释。


1
投票

这个问题似乎是Doctrine 2 DQL MySQL相当于ROUND()的重复?

您需要为此实现一个 自定义 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');

0
投票

Doctrine ORM v2.19.0
起,升级指南中进行了更改


弃用 Doctrine\ORM\Query\Lexer::T_* 常量

使用 Doctrine\ORM\Query\TokenType::T_* 代替。


更新了代码示例

<?php

namespace App\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
use Doctrine\ORM\Query\TokenType;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\QueryException;

class InetAton extends FunctionNode
{
    private SimpleArithmeticExpression $arithmeticExpression;

    /**
     * @param SqlWalker $sqlWalker
     * @return string
     */
    public function getSql(SqlWalker $sqlWalker): string
    {
        return 'INET_ATON(' . $sqlWalker->walkSimpleArithmeticExpression(
            $this->arithmeticExpression
        ) . ')';
    }

    /**
     * @param Parser $parser
     * @return void
     * @throws QueryException
     */
    public function parse(Parser $parser): void
    {
        $parser->match(TokenType::T_IDENTIFIER);
        $parser->match(TokenType::T_OPEN_PARENTHESIS);

        $this->arithmeticExpression = $parser->SimpleArithmeticExpression();

        $parser->match(TokenType::T_CLOSE_PARENTHESIS);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.