【问题标题】:Symfony Doctrine creating complex queriesSymfony Doctrine 创建复杂查询
【发布时间】:2015-08-09 23:21:49
【问题描述】:

我有一个 mysql 查询,它并不是很复杂,但我似乎无法弄清楚我应该如何在 Symfony 中编写它。

首先是查询:

select
   db1.table1.acronym
 , db1.table1.name
 , db2.table1.name
from db1.table1, db2.table1 
where db1.table1.acronym like concat('%', @t1, '%') 
or db1.table1.name like concat('%', @t1,'%') 
or db2.table1.name like concat('%', @t1,'%');

我基本上是想看看 t1 是否是这些列中任何单词的一部分。假设@t1 是一个被传递的变量。我不确定我是否应该将其写在存储库中,如果可以,如何写。我正在寻找最佳实践方法。

谢谢。

【问题讨论】:

    标签: mysql symfony doctrine-orm


    【解决方案1】:

    首先,您需要为第一个数据库和第二个数据库配置两个 Doctrine DB 连接。它看起来像这样(我假设您还没有为表创建实体):

    //in config.yml
    
    doctrine:
        dbal:
            default_connection: db1
            connections:
                db1:
                    driver:   "%database_driver%"
                    host:     "%database_host%"
                    port:     "%database_port%"
                    dbname:   "%database_name%"
                    user:     "%database_user%"
                    password: "%database_password%"
                    charset:  UTF8
                db2:
                    driver:   "%database_driver%"
                    host:     "%database_host%"
                    port:     "%database_port%"
                    dbname:   "%database_name2%"
                    user:     "%database_user%"
                    password: "%database_password%"
                    charset:  UTF8
    

    注意这里我们使用 'dbname' 中的参数 database_name2 进行 db2 连接,其他参数很可能是相同的,除非您在另一台服务器上有其他数据库,因此您应该在 parameters.yml 中相应地创建参数。

    然后,您可以在例如控制器操作中获得与单独数据库的连接,如下所示:

    //SomeController.php
    
    $connection1 = $this->getDoctrine()->getConnection('db1');
    $connection2 = $this->getDoctrine()->getConnection('db2');
    
    
    $results1 = $connection1->fetchAll('SELECT acronym, name FROM table1 ...');
    $results2 = $connection2->fetchAll('SELECT name FROM table2 ...')
    

    注意,这不是最佳做法。最佳做法是为表创建实体,然后沿着我上面创建的连接创建单独的实体管理器。

    How to properly setup multiple connections with entity managers

    【讨论】:

    • 另外没有提到的是编辑parameters.yml 来让config.yml 变量像dbname: "%database_name2%" parameters.yml: parameters: database_host: 127.0.0.1 database_port: null database_user: myusername database_password: mypassword database_name: db1 mailer_transport: smtp mailer_host: 127.0.0.1 mailer_user: null mailer_password: null secret: fsfaffffafaf database_host2: 127.0.0.1 database_port2: null database_user2: meusername database_password2: password database_name2: db2
    【解决方案2】:

    您的查询没有连接,所以我不确定您要在这里实现什么,但如果您只想找到 db1.table1db2.table1 中的所有实体,这些确实应该是2 个单独的查询。

    同样使用 Doctrine,很难使用多个数据库,所以除非你有充分的理由,否则我建议你将两个表移动到同一个数据库并将 db2.table1 重命名为 db1.table2

    在此之后,Table1Repository 中的 QueryBuilder 查找 table1 中的实体会这样:

    public function findByNameOrAcronymLike($nameOrAcronym) {
            $qb = $this->createQueryBuilder('table1')
                ->where('table1.acronym LIKE :t1')
                ->or('table1.name LIKE :nameOrAcronym')
                ->setParameter('nameOrAcronym', addcslashes($nameOrAcronym, '_%'))
                ->getQuery()
                ->execute();
    }
    

    还有Table2Repository中的QueryBuilder:

    public function findByNameLike($name) {
            $qb = $this->createQueryBuilder('table2')
                ->where('table2.name LIKE :name')
                ->setParameter('name', addcslashes($name, '_%')
                ->getQuery()
                ->execute();
    }
    

    addcslashes 调用被添加到转义 %_ - 这些在 LIKE 说明符中被视为特殊字符

    【讨论】:

    猜你喜欢
    • 2018-08-23
    • 2015-05-12
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2013-11-07
    相关资源
    最近更新 更多