你如何在Symfony2服务类中访问Doctrine DBAL?

27
我正在学习Symfony2(和面向对象编程),想要创建一个在整个应用程序中都可用的服务。这个服务接收一个值foo,将其与数据库表进行比较,并返回一个值bar。
我有一个小类。
namespace Acme\TestBundle\Toolbox;

class StringToolbox
{
    public function lookupSomething($foo)
   {

        $conn = $this->get('database_connection');
        $sql = "SELECT bar FROM bar_list WHERE foo = :foo";
        $stmt = $conn->prepare($sql);
        $stmt->bindValue("foo", $foo);
        $stmt->execute();


        return $bar;
    }


}

我的设置如下:

services:
    toolbox:
       class:        Acme\TestBundle\Toolbox
        arguments:   [@database_connection]

但是它会抛出一个错误,说get()方法未定义。 我卡住了 - 如何在服务中使用DBAL? 谢谢!

2个回答

40

首先,您应该向您的类添加一个构造函数,并传入@doctrine.dbal.%connection_name%_connection service

namespace Acme\TestBundle\Toolbox;
use Doctrine\DBAL\Connection;

class StringToolbox
{
    /**
    *
    * @var Connection
    */
    private $connection;

    public function __construct(Connection $dbalConnection)  {
        $this->connection = $dbalConnection;    
    }

    public function lookupSomething($foo)
    {

    $sql = "SELECT bar FROM bar_list WHERE foo = :foo";
    $stmt = $this->connection->prepare($sql);
    $stmt->bindValue("foo", $foo);
    $stmt->execute();


    return $bar;
    }


}

您的服务配置现在应该像这样:

parameters:
 my_service_connection: default

services:
 toolbox:
   class:        Acme\TestBundle\Toolbox\StringToolbox
    arguments:   [@doctrine.dbal.%my_service_connection%_connection]

你在这个配置中所说的是"创建一个名为toolbox的服务,并将doctrine.dbal.default_connection服务作为第一个构造函数参数传递"

除了构造函数注入之外,还有其他注入方法。你应该阅读http://symfony.com/doc/current/book/service_container.html文档,了解所有可能性(如Setter注入、Factory注入等),并更好地理解依赖注入的工作原理。


这非常有帮助!Symfony文档非常好,但是它们假设你具备完全的面向对象编程知识,而我有一些空白。谢谢! - Acyra
由于某些原因,这不再起作用,我必须传递不同的参数:arguments: [@database_connection] - Acyra
6
@doctrine.dbal.connection服务是一个抽象层。尝试使用 @doctrine.dbal.%connection_name%_connection,其中 %connection_name% 是您要注入的连接名称的占位符。 - Igor Timoshenko
@catalin.costache 非常感谢您的快速回复。我有一个疑问。我使用这种方法是因为我需要连接几个数据库,例如clientAclientGclientX。我可以在parameters.yml文件中定义变量,比如说my_service_connection: clientA。然而,在运行时,当我实例化我的服务时,从我的服务中如何知道/如何让它知道我想要连接到clientAclientXclientG - Nis
@Nis,你可以随时注入@doctrine服务,它是一个http://www.doctrine-project.org/api/common/2.4/class-Doctrine.Common.Persistence.AbstractManagerRegistry.html的子类。请参考:https://github.com/doctrine/DoctrineBundle/blob/master/Resources/config/dbal.xml - catalin.costache
显示剩余2条评论

11

@doctrine.dbal.connection 无法运行。正如Igor所说,@doctrine.dbal.connection 是一个抽象类,请使用@doctrine.dbal.default_connection 如果你只有一个数据库连接,或者使用@doctrine.dbal.%connection_name%_connection 其中%connection_name% 占位符是你想要注入的连接名称。

你的服务配置现在应该像这样:

services:
 toolbox:
   class:        Acme\TestBundle\Toolbox\StringToolbox
    arguments:   [@doctrine.dbal.default_connection]

谢谢您的回答。如果我们使用@doctrine.dbal.%connection_name%_connection方法,那么我们如何传递所需连接的%connection_name%呢? - Nis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接