草庐IT

php - 在 Doctrine DBAL 中重用 QueryBuilder

coder 2024-04-17 原文

以下示例显示了代码示例的一些摘录。在那里调用 Doctrine DBAL 的 QueryBuilder 两次 - 一次执行 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;
}

最佳答案

Doctrine DBAL 中的 QueryBuilder 可以动态地用于定义 SQL 查询,也可以再次覆盖查询部分。因此,通常在同一个 QueryBuilder 实例上两次调用 select() 方法会覆盖之前的 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;
}

关于php - 在 Doctrine DBAL 中重用 QueryBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40069020/

有关php - 在 Doctrine DBAL 中重用 QueryBuilder的更多相关文章

  1. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  2. ruby-on-rails - 在 Rails 中分配和重用变量 - 设计模式 - 2

    我一直在使用相同的模式来返回json代码(参见下面的示例)。我正在收集照片并将其存储在变量中。如果存在标记参数,我将获得一个更具体的集合并将其重新分配给同一个变量。然后将其作为json返回。什么是更好的设计模式来实现同样的事情?photos=collection_of_photosifparams[:tag]photos=photos.find_all{|photo|somecondition}endrenderjson:photos 最佳答案 如果照片是ActiveRecord对象,您应该使用scope为您需要的确切数据生成适当的

  3. ruby-on-rails - 在多个 Rails 模型中重用方法 - 2

    此处为初学者ruby​​/rails问题。我有一个方法,我目前正在我的“用户”模型中使用。defgenerate_token(列)开始self[列]=SecureRandom.urlsafe_base64在User.exists时结束?(列=>self[列])结束我想在不同的模型中重复使用相同的方法,比如我的帐户模型。在哪里放置这样的代码以便在模型之间共享是个好地方?另外,为了获得调用类,我是否只使用“self.class”?谢谢 最佳答案 Rails4关注点就是为了完成这项工作。http://api.rubyonrails.org

  4. ruby-on-rails - Ruby On Rails - 重用错误消息部分 View - 2

    问题我试图在我的View中重用错误消息block。下面是positions/_error_messages.html.erb中写的blockTheformcontains.*问题是我必须在每个模型中创建类似的部分View,这有点像用不同的对象重复相同的代码,即@user、@client等。补救措施我在共享文件夹shared/_error_messages.html.erb中创建了一个erb并编写了以下代码。Theformcontains.*然后在查看文件中。positions/new.html.erb我写了下面的代码这意味着现在我可以在所有创建和更新操作中使用相同的代码。我想知道,这样

  5. ruby-on-rails - Rails 还是 Sinatra? PHP程序员入门学习哪个好? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?

  6. ruby - 不同 Ruby 项目之间代码重用的最佳实践是什么? - 2

    伙计们!我是一名具有Java背景的软件开发人员,我正在使用Ruby网络框架(Padrino/Sinatra)开始一些项目。在我的java项目中,我通常有一些“公共(public)”项目,其类在多个项目中使用。例如,我有一个中央身份验证服务和一个存储用户配置文件的共享数据库。我所有使用此服务的项目都共享一些映射到用户配置文件数据库的模型。那么,尽管有框架、orm库等,跨多个Ruby项目共享代码的最佳方式是什么? 最佳答案 除此之外,ruby'sgems是重用代码公共(public)部分的最佳方式之一。Gem具有名称、版本号和描述,因此

  7. ruby-on-rails - PHP 魔术方法 __call、__get 和 __set 的 Ruby 等价物 - 2

    我很确定Ruby有这些(等同于__call、__get和__set),否则find_by将如何在Rails中工作?也许有人可以举一个简单的例子来说明如何定义与find_by相同的方法?谢谢 最佳答案 简而言之你可以映射__调用带有参数的method_missing调用__设置为方法名称以'='结尾的method_missing调用__获取不带任何参数的method_missing调用__调用PHPclassMethodTest{publicfunction__call($name,$arguments){echo"Callingob

  8. ruby - Lisp - 是否适合网络编程/应用程序(交互式)? ruby 的方式是? php的方式是? - 2

    Lisp是否适合Web编程/应用程序(交互式),就像ruby​​和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common

  9. 软件工程毕业设计课题(81)微信小程序毕业设计PHP校园跑腿小程序系统设计与实现 - 2

        项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信校园跑腿小程序系统,前台用户使用小程序发布跑腿任何和接跑腿任务,后台管理使用基于PHP+MySql的B/S架构;通过后台管理跑腿的用户、查看跑腿信息和对应订单。意义:手机网络时代,大学生通过手机网购日常用品、外卖外卖、代取快递等已不再是稀奇的事情。此外,不少高校还流行着校园有偿工作,校园跑腿就成了大学生创业服务项目。        因为你在校园里,所以不会有进入的限制。并不是所有的外卖平台都可以随意进入校园,比如小黄和小蓝的双打外卖平台。许多大学禁止送餐进入学校,更不用说送餐进入宿舍了。这一措施使得校园服务市场的竞争相对不

  10. K8s部署PHP项目 - 2

    前言    前端时间PHP项目部署升级需要,需要把Laravel开发的项目部署K8s上,下面以laravel项目为例,讲解采用yaml文件方式部署项目。一、部署步骤1.创建Dockerfile文件Dockerfile是一个用来构建镜像的文本文件,在容器运行时,需要把项目文件和项目运行所必须的组件安装其中。#基础镜像FROMphp:7.4-fpm#时区ARGTZ=Asia/Shanghai#更换容器时区RUNcp"/usr/share/zoneinfo/$TZ"/etc/localtime&&echo"$TZ">/etc/timezone#替换成阿里apt-get源RUNsed-i"s@http

随机推荐