简体   繁体   English

教义查询生成器和Silex

[英]Doctrine Query Builder and Silex

In my Silex project I use the Doctrine Query Builder from the Database Abstraction Layer package. 在我的Silex项目中,我使用“数据库抽象层”程序包中的“ Doctrine查询生成器”。

"doctrine/dbal": "^2.5"

I register it in my application container like this. 我这样在我的应用程序容器中注册它。

/**
 * 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']);
};

When I want to query for database records I am using a repository pattern and then inject the query builder instance into the repository and then I use the query builder in the repository my repositories are created like this. 当我想查询数据库记录时,我正在使用存储库模式,然后将查询构建器实例注入存储库中,然后在存储库中使用查询构建器,我的存储库就是这样创建的。

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

In the user repository I query for an user to fetch the id and after that I query the book repository for the books that belong to the user, however the problem is that when I use the query builder in the book repository it is already filled with the previous user table. 在用户存储库中,我查询一个用户以获取ID,然后在图书存储库中查询属于该用户的图书,但是问题是,当我在图书存储库中使用查询生成器时,该查询生成器已被填充上一个用户表。 Do I need to reset the query builder instance or am I doing something wrong with registering the query builder into the container. 我是否需要重置查询生成器实例,还是在将查询生成器注册到容器时做错了什么。

QueryBuilder is registered as a usual service and as such only one instance of it will be created. QueryBuilder被注册为常规服务,因此将仅创建它的一个实例。 If you happen to populate any user data to it before you query some books, that's the way it is. 如果您在查询某些书籍之前碰巧要在其中填充任何用户数据,那就是这样。

To avoid this problem, you might define db.builder as a factory service*. 为避免此问题,您可以将db.builder定义为工厂服务*。 That way, every time you request it, a new instance will be created: 这样,每次您请求时,都会创建一个新实例:

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

Read more about service definitions in Silex at http://silex.sensiolabs.org/doc/master/services.html . http://silex.sensiolabs.org/doc/master/services.html上了解有关Silex中服务定义的更多信息。

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

By default services are shared, so when you ask for some service $app['xxx'] same copy is returned. 默认情况下,服务是共享的,因此当您请求某些服务$app['xxx']将返回相同的副本。 You should say to container that function that returns service is a factory to get new instance on each call. 您应该对容器说返回服务的函数是在每次调用中获取新实例的工厂。

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

In any case query builder will be filled with something after second call to repository, in your case repository keeps and uses one copy of query builder. 无论如何,在第二次调用存储库后,查询构建器将充满某些东西,在您的情况下,存储库将保留并使用查询构建器的一个副本。 Better keep db in your repository, add method to get new query builder and use it in methods that select data from 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...;
    }
}

Or move to Doctrine ORM 或移至学说ORM

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM