douxian8883 2013-07-23 21:36
浏览 22
已采纳

如何减少Doctrine正在执行的查询数量?

I'm building a product management tool where the product can have an arbitrary number of attributes, documents, features, images, videos as well as a single type, brand, and category. There are a few other related tables, but this is enough to demonstrate the problem.

There's a Model class called ProductModel that contains a method like this (reduced for clarity):

  public function loadValues() {
    //Product entity data
    $this->id = $this->entity->getId();
    $this->slug = $this->entity->getSlug();

    // One of each of these
    $this->loadType();
    $this->loadBrand();
    $this->loadCategory();

    // Arbitrary number of each of these
    $this->loadAttributes();
    $this->loadDocuments();
    $this->loadFeatures();
    $this->loadImages();
    $this->loadVideos();
    ...
  }

Each of the load methods does some boiler plate that eventually executes this method:

  public function loadEntitiesByProductId($productId=0) {

    // Get all the entities of this type that are associated with the product.
    $entities = $this->entityManager
      ->getRepository($this->entityName)
      ->findByProduct($productId);

    $instances = array();

    // Create a Model for each entity and load the data.
    foreach ($entities as $entity) {
      $id = $entity->getId();
      $instances[$id] = new $this->childClass();
      $instances[$id]->entity = $entity;
      $instances[$id]->loadValues();
    }

    return $instances;

  }

This is OK for cases where the related entity is a single table, but usually it's a mapper. In those cases, I get all the mapper entities in the first query then I have to query for the related entity within the loadValues() method (via Doctrine's get<Entity>() method). The result of this process is a huge number of queries (often >100). I need to get rid of the extraneous queries, but I'd like to do so without losing the idioms I'm using across my data models.

Is there a way to get the entityManager to do a better job at using joins to group these queries?

  • 写回答

1条回答 默认 最新

  • du9843 2013-07-26 15:08
    关注

    There were a couple problems with my previous approach:

    First, I was getting the entities from the repository instead of loading them from the existing entity:

    $entities = $this->entityManager
      ->getRepository($this->entityName)
      ->findByProduct($productId);
    

    Better is:

    $method = $this->deriveGetMethod($this->entityName);
    $entities = $productEntity->$method()
    

    Second, I was retrieving the product entity using $this->entityManager->getRespository... which works fine for loading small data sets (a single table or one or two relations), but there's no way to get the repository's findBy methods to load relations in a single query. The solution is to use the queryBuilder.

    $qb = $this->entityManger->createQueryBuilder();
    $query = $this->select('product',/*related tables*/)->/*joins etc.*/
    $productEntity = $query->getSingleResult();
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀