繁体   English   中英

教义查询生成器和Silex

[英]Doctrine Query Builder and Silex

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

"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,然后在图书存储库中查询属于该用户的图书,但是问题是,当我在图书存储库中使用查询生成器时,该查询生成器已被填充上一个用户表。 我是否需要重置查询生成器实例,还是在将查询生成器注册到容器时做错了什么。

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

暂无
暂无

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

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