Doctrine查询生成器和Silex

问题描述:

在我的Silex项目中,我使用数据库抽象层包中的Doctrine查询生成器。Doctrine查询生成器和Silex

"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之后,我查询属于用户本本的书库,但问题是,当我使用查询生成器在图书库已经充满了以前的用户表。我是否需要重置查询构建器实例,或者我在将查询构建器注册到容器中时做了什么问题?

+0

什么是您的硅石版本? –

+0

@MaxP。 “silex/silex”:“〜2.0” – DB93

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

默认情况下,服务是共享的,所以当你要求一些服务返回$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...; 
    } 
} 

或移至学说ORM