3

質問: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関数の前後に引用符を追加します。

4

3 に答える 3

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

その後、DoctrineORMに関数を追加します

<?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とZendFramework2の特別な機能を持つ他の人に役立つことを願っています

于 2013-03-26T06:10:19.820 に答える
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の公式ドキュメントで説明されています。

于 2016-01-12T22:42:39.270 に答える
1

この質問は、ROUND()と同等のDoctrine 2 DQLMySQLの複製のようです。

そのためにカスタム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');
于 2013-03-26T06:09:22.037 に答える