在Doctrine DBAL中重用QueryBuilder

奥利弗·哈德(Oliver Hader)

下面的示例显示了一些代码示例的摘录。QueryBuilder那里,对Doctrine DBAL的调用要进行两次,一次是执行一条SELECT(*)语句,另一次是执行一条COUNT(*)语句。

表,条件,排序顺序和结果限制之类的常用设置将应用于重用QueryBuilder对象。

问题

  • 是否存在$queryBuilder如示例中所示的隐式重用的缺点
  • 是否建议只为单独的QueryBuilder实例复制粘贴代码
  • 使用有副作用clone $queryBuilder吗?

代码示例

/**
 * @param array $arguments
 * @return string
 */
private function getOutput(array $arguments)
{
    /** @var \Doctrine\DBAL\Connection $connection */
    $connection = $this->getConnection();

    $queryBuilder = $connection
        ->createQueryBuilder()
        ->from('some_table')
        ->orderBy('sorting')
        ->setMaxResults(100);

    $condition = $queryBuilder->expr()->andX();
    // ... build conditions
    $queryBuilder->where($condition);

    $count = $queryBuilder->select('COUNT(*)')->execute()->fetchColumn(0);
    if ($count === 0) {
        return 'There is nothing to show';
    }
    if ($count > 100) {
        $output = 'Showing first 100 results only:' . PHP_EOL;
    } else {
        $output = 'Showing all results:' . PHP_EOL;
    }

    // implicitly reusing previously defined settings
    // (table, where, orderBy & maxResults)
    $statement = $queryBuilder->select('*')->execute();
    foreach ($statement as $item) {
        $output .= $this->renderItem($item) . PHP_EOL;
    }

    return $output;
}
奥利弗·哈德(Oliver Hader)

Doctrine DBAL中的QueryBuilder可以动态用于定义SQL查询,也可以再次覆盖查询部分。因此,通常select()在同一QueryBuilder实例上两次调用该方法会覆盖前一个select查询部分。构建器内部具有用于清除或脏状态的属性-状态一旦变脏,就必须重新创建SQL字符串。例如,覆盖查询部分会触发脏状态。

因此,从简单的技术角度来看,通常可以重用QueryBuilder。但是,QueryBuilder不会验证跨数据库的特定逻辑。这意味着,多余的查询部分必须手动清除,以免执行语句时查询失败。

更好的方法是将构建查询的过程分为不同的逻辑类方法-一种用于分配公共查询约束,另一种用于特定上下文(例如,对结果进行计数,对结果进行排序和限制结果集)。最后,初始代码示例可能如下所示:

引入了两种其他方法来丰富查询

/**
 * @param QueryBuilder $queryBuilder
 */
private function addConstraints(QueryBuilder $queryBuilder)
{
    $condition = $queryBuilder->expr()->andX();
    // ... build conditions
    $queryBuilder->where($condition);
}

/**
 * @param QueryBuilder $queryBuilder
 */
private function addResultSettings(QueryBuilder $queryBuilder)
{
    $queryBuilder
        ->orderBy('sorting')
        ->setMaxResults(100);
}

现在有QueryBuilder的两个实例,但是查询基本上是在前面显示的两个新方法中定义的。

/**
 * @param array $arguments
 * @return string
 */
private function getOutput(array $arguments)
{
    /** @var \Doctrine\DBAL\Connection $connection */
    $connection = $this->getConnection();

    // first query builder instance for counting records
    $queryBuilder = $connection->createQueryBuilder()->from('some_table');
    $this->addConstraints($queryBuilder);
    $statement = $queryBuilder->select('COUNT(*)')->execute();

    $count = $statement->fetchColumn(0);
    if ($count === 0) {
        return 'There is nothing to show';
    }
    if ($count > 100) {
        $output = 'Showing first 100 results only:' . PHP_EOL;
    } else {
        $output = 'Showing all results:' . PHP_EOL;
    }

    // second query builder instance to actually retrieve result set
    $queryBuilder = $connection->createQueryBuilder()->from('some_table');
    $this->addConstraints($queryBuilder);
    $this->addResultSettings($queryBuilder);
    $statement = $queryBuilder->select('*')->execute();

    foreach ($statement as $item) {
        $output .= $this->renderItem($item) . PHP_EOL;
    }

    return $output;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Doctrine中的自定义QueryBuilder

从Doctrine QueryBuilder中的数组中选择列

Doctrine 2 DBAL 和 QueryBuilder - 它真的有效吗?

SQL 到 Doctrine 的 QueryBuilder 转换

使用Doctrine QueryBuilder忽略参数

与多义关系中的Doctrine QueryBuilder不在查询中

如何在doctrine2 queryBuilder中实现ON(... OR ...)mysql查询

WHERE ...在Doctrine queryBuilder或同等查询中的带子查询的IN查询

Symfony2-Doctrine2 QueryBuilder在ManyToMany字段中

Doctrine 2 ORM-在oneToMany关系中搜索(QueryBuilder)

从 Doctrine ORM QueryBuilder 中实体的两列获取数据

无法加载类型“Doctrine\DBAL\Types\TextType”

更改Laravel迁移中的列会导致异常:更改表的列需要Doctrine DBAL

Doctrine \ DBAL \ Schema \ SchemaException:如何在声明的表索引中包括一个或多个FK

Symfony:如何在Doctrine DBAL配置(YAML)中设置SSL参数?

使用Doctrine querybuilder正确转义LIKE查询

完全不匹配的Doctrine2 QueryBuilder

如何使用Doctrine QueryBuilder删除多个实体

类型为“ Doctrine \ ORM \ QueryBuilder”的预期参数

QueryBuilder / Doctrine选择加入分组依据

doctrine2 querybuilder不之间

如何使用QueryBuilder和Doctrine数组类型?

Symfony配置:Doctrine InvalidConfigurationException:“ doctrine.dbal”下的无法识别的选项“ options”

使用Doctrine \ DBAL \ Exception捕获数据库错误

在Symfony中使用Doctrine的DBAL检索布尔值

在模块内部执行Doctrine Dbal查询的存储库

具有数组值的Doctrine DBAL setParameter()

无法使用Doctrine \ DBAL \ Schema \ Table创建表

找不到类“Doctrine\DBAL\Driver\PDOMySql\Driver”