【问题标题】:Doctrine Query Builder and SilexDoctrine 查询生成器和 Silex
【发布时间】:2017-01-13 22:48:40
【问题描述】:

在我的 Silex 项目中,我使用 Database Abstraction Layer 包中的 Doctrine Query Builder。

"doctrine/dbal": "^2.5"

我像这样在我的应用程序容器中注册它。

/**
 * Make a connection to the database.
 */
$app['db'] = function() use($app) {
    $connectionParams = [
        'dbname' => $_ENV['DBNAME'],
        'user' => $_ENV['DBUSER'],
        'password' => $_ENV['DBPASS'],
        'host' => $_ENV['DBHOST'],
        'driver' => $_ENV['DBDRIVER'],
    ];

    return \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
};

/**
 * Instantiate the query builder
 */
$app['db.builder'] = function() use($app) {
    return new \Doctrine\DBAL\Query\QueryBuilder($app['db']);
};

当我想查询数据库记录时,我使用存储库模式,然后将查询构建器实例注入存储库,然后我在存储库中使用查询构建器,我的存储库是这样创建的。

$app['repository.user'] = function() use($app) {
    return new App\Repositories\UserRepository($app['db.builder']);
};

$app['repository.book'] = function() use($app) {
    return new App\Repositories\BookRepository($app['db.builder']);
};

在用户存储库中,我查询用户以获取 id,然后我在图书存储库中查询属于该用户的书籍,但是问题是当我在图书存储库中使用查询构建器时,它是已经填满了之前的用户表。我是否需要重置查询生成器实例,或者我在将查询生成器注册到容器时做错了什么。

【问题讨论】:

  • 你的 silex 版本是什么?
  • @MaxP。 "silex/silex": "~2.0"

标签: php symfony doctrine-orm silex dbal


【解决方案1】:

QueryBuilder 已注册为常规服务,因此只会创建它的一个实例。如果您在查询某些书籍之前碰巧填充了任何用户数据,那就是这样。

为避免此问题,您可以将db.builder 定义为工厂服务*。这样,每次您请求它时,都会创建一个新实例:

$app['db.builder'] = $app->factory(function () use ($app) {
    return new \Doctrine\DBAL\Query\QueryBuilder($app['db']);
});

在http://silex.sensiolabs.org/doc/master/services.html 上阅读有关 Silex 中服务定义的更多信息。

*http://silex.sensiolabs.org/doc/master/services.html#factory-services

【讨论】:

    【解决方案2】:

    默认情况下服务是共享的,所以当你请求某些服务$app['xxx'] 时,会返回相同的副本。您应该对容器说,返回服务的函数是一个工厂,可以在每次调用时获取新实例。

    $app['db.builder'] = $app->factory(function() use($app) {
        return new \Doctrine\DBAL\Query\QueryBuilder($app['db']);
    });
    

    在任何情况下,查询构建器都会在第二次调用存储库后填充一些内容,在您的情况下,存储库会保留并使用查询构建器的一个副本。最好将 db 保留在您的存储库中,添加方法以获取新的查询生成器并将其用于从数据库中选择数据的方法中。

    $app['repository.book'] = function() use($app) {
        return new App\Repositories\BookRepository($app['db']);
    };
    
    class \App\Repositories\BookRepository
    {
        protected $db;
        protected $table = 'book';
    
        public function __construct($db)
        {
            $this->db = $db;
        }
    
        public function getQueryBuilder()
        {
            $qb = new \Doctrine\DBAL\Query\QueryBuilder($this->db);
            $qb->from($this->table);
            return $qb;
        }
    
        public function find1()
        {
            $qb = $this->getQueryBuilder();
            $qb...;
            return...;
        }
    
        public function find2()
        {
            $qb = $this->getQueryBuilder();
            $qb...;
            return...;
        }
    }
    

    或者转向 Doctrine ORM

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      相关资源
      最近更新 更多