为什么symfony会对连接执行额外的查询

时间:2014-07-23 12:59:08

标签: mysql symfony many-to-many

我尝试使用带有连接的myisam表从数据库加入many2many。

我有表格文章,article_category,actor,article_actor(以及更多类似的many2many关系)。

我的设置

文章:

  
class Article{
//....

/**
 * @ORM\ManyToMany(targetEntity="Category", inversedBy="articles")
 * @ORM\JoinTable(name="article_category")
 */
protected $categories;

/**
 * @ORM\ManyToMany(targetEntity="Actor", inversedBy="articles")
 * @ORM\JoinTable(name="article_actor")
 */
protected $actors;

/**
 * @ORM\ManyToMany(targetEntity="Cameraman", inversedBy="cameramen")
 * @ORM\JoinTable(name="article_cameraman")
 */
public function __construct() {
  $this->categories = new ArrayCollection();
  $this->actors = new ArrayCollection();
}
  

类别:

  

类别类别{

/**   
 * @ORM\ManyToMany(targetEntity="Article", mappedBy="categories")
 **/  
protected $articles;       

public function __construct() { 
  $this->articles = new ArrayCollection();
}

演员:

  

类演员{

/**   
 * @ORM\ManyToMany(targetEntity="Article", mappedBy="actors")
 **/  
protected $articles;

public function __construct() {
  $this->articles = new ArrayCollection();
}

在ArticleRepository中,我有一个带连接的查询:

  

类ArticleRepository扩展了EntityRepository {
  公共函数findArticleWithJoins($ _ titleSlug){

$q = $this->createQueryBuilder('a')
  ->where('a.titleSlug = :titleSlug')
  ->setParameter('titleSlug', $_titleSlug)
  ->leftJoin('a.categories', 'c')
  ->leftJoin('a.actors', 'ac')


return $q->getQuery()->getSingleResult();   
     

}   }

在我的控制器中,我获取带有相关联接的文章:

$em = $this->getDoctrine()->getManager();
$article = $em->getRepository('MyBundle:Article')->findArticleWithJoins('theSlug'); 
return $this->render('MyBundle:Default:index.html.twig',array('article' => $article));

最后在模板中,一旦我遍历连接,就有3个查询:

{% block body %}
  {{article.title}}<br/>
  {{article.categories.0.name}}<br/>
  {% for actor in article.actors %}
    <li>{{ actor.firstName }} {{ actor.lastName }}</li>
  {% endfor %}
{% endblock %}

第一个问题是:

SELECT 
  a0_.id AS id0,  
  a0_.title AS title15, 
  a0_.orig_title AS orig_title16, 
  a0_.title_slug AS title_slug17, 

FROM 
  article a0_ 
  LEFT JOIN article_category a2_ ON a0_.id = a2_.article_id 
  LEFT JOIN category c1_ ON c1_.id = a2_.category_id 
  LEFT JOIN article_actor a4_ ON a0_.id = a4_.article_id 
  LEFT JOIN actor a3_ ON a3_.id = a4_.actor_id 
WHERE 
  a0_.title_slug = ?

第二个问题:

SELECT 
  t0.id AS id1, 
  t0.name AS name2, 
  t0.slug AS slug3, 
FROM 
  category t0 
  INNER JOIN article_category ON t0.id = article_category.category_id 
WHERE 
  article_category.article_id = ?

第三个问题:

SELECT 
  t0.id AS id1, 
  t0.first_name AS first_name2, 
  t0.last_name AS last_name3, 
  t0.name_slug AS name_slug4, 
FROM 
  actor t0 
  INNER JOIN article_actor ON t0.id = article_actor.actor_id 
WHERE 
  article_actor.article_id = ?

我想通过使用findArticleWithJoins()函数中的连接来避免多个查询。 但结果只是查询文章然后再选择关系。

我做错了吗?

1 个答案:

答案 0 :(得分:2)

在查询中添加select(->select('a, c, ac')

$q = $this->createQueryBuilder('a')
  ->select('a, c, ac')
  ->where('a.titleSlug = :titleSlug')
  ->setParameter('titleSlug', $_titleSlug)
  ->leftJoin('a.categories', 'c')
  ->leftJoin('a.actors', 'ac')

这将使学说用关系构建对象。