预加载与Doctrine的ManyToMany关系

时间:2015-10-06 09:59:26

标签: performance doctrine-orm query-builder relationships preload

我在尝试预加载ManyToMany关系时遇到了一些问题。我有人与Segments有关;人们属于群组,当我加载群组时,我想用他们的段来预加载所有人。

这是(简化的)映射:

组:

Cerebrum\ORM\GroupEntity:
  type: entity
  table: groups
  id:
    uuid:
      type: integer
      column: id
      generator: { strategy: AUTO }
      options: { unsigned: true }
  fields:
    name:
      type: string
      length: 200
      unique: true
      column: group_name
  manyToMany:
    people:
      targetEntity: Cerebrum\ORM\PersonEntity
      cascade: ["persist"]
      mappedBy: groups

人:

Cerebrum\ORM\PersonEntity:
  type: entity
  table: persons
  id:
    uuid:
      type: integer
      column: id
      generator: { strategy: AUTO }
      options: { unsigned: true }
  fields:
    username:
      type: string
      length: 50
      nullable: true
      unique: true
  manyToMany:
    groups:
      targetEntity: Cerebrum\ORM\GroupEntity
      cascade: ["persist", "remove"]
      inversedBy: people
      joinTable:
        name: groups_persons
        joinColumns:
          person_id:
            referencedColumnName: id
            onDelete: CASCADE
        inverseJoinColumns:
          group_id:
            referencedColumnName: id
            onDelete: CASCADE
    segments:
      targetEntity: Cerebrum\ORM\SegmentEntity
      cascade: ["persist"]
      inversedBy: people
      joinTable:
        name: segments_persons
        joinColumns:
          person_id:
            referencedColumnName: id
            onDelete: CASCADE
        inverseJoinColumns:
          segment_id:
            referencedColumnName: id
            onDelete: CASCADE

段:

Cerebrum\ORM\SegmentEntity:
  type: entity
  table: segments
  id:
    uuid:
      type: integer
      column: id
      generator: { strategy: AUTO }
      options: { unsigned: true }
  fields:
    name:
      type: string
      length: 200
      unique: true
      column: segment_name
  manyToMany:
    people:
      targetEntity: Cerebrum\ORM\PersonEntity
      cascade: ["persist"]
      mappedBy: segments

当我加载一个组时,我尝试这种方法:

<?php
$builder = $entityManager->createQueryBuilder();
$builder->select('p,s')
    ->from('Cerebrum\ORM\PersonEntity', 'p')
    ->leftJoin('Cerebrum\ORM\SegmentEntity', 's')
    ->where('p.uuid IN (:persone)');
$builder->setParameter('persone', $this->entity->getPeople());
$query = $builder->getQuery();

如果我尝试$query->getDQL(),我会获得SELECT p,s FROM Cerebrum\ORM\PersonEntity p LEFT JOIN Cerebrum\ORM\SegmentEntity s WHERE p.uuid IN (:persone),如果我循环浏览$query->getResult(),我会获得PersonEntity和SegmentEntity列表。问题是PersonEntities没有加载关系,正如你在这个转储中看到的那样:

Cerebrum\ORM\PersonEntity {#427
  -uuid: 1
  -username: "argonauta"
  -segments: Doctrine\ORM\PersistentCollection {#464
    -snapshot: []
    -owner: Cerebrum\ORM\PersonEntity {#427}
    -association: array:20 [ …20]
    -em: Doctrine\ORM\EntityManager {#108 …11}
    -backRefFieldName: "people"
    -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#428 …}
    -isDirty: false
    #collection: Doctrine\Common\Collections\ArrayCollection {#465
      -elements: []
    }
    #initialized: false
  }
}

这导致对数据库的大量查询,因为每个人都使用单个查询加载他的Segments。我知道我需要所有这些信息,因此我可以选择使用单个查询预加载它们。

你有什么暗示吗?我整个上午都在谷歌上搜索: - (

0 个答案:

没有答案