我有多语言项目,我使用symfony2 + doctrine。
如果我尝试以不同于默认语言的语言显示对象列表,则doctrine会生成一个查询以获取所有对象的所有数据,然后为每个对象生成一个查询,这是不必要的。
存储库代码中的代码如下所示:
$repository = $this->_em->getRepository($this->_entityName);
$keywordController = new \Cms\Bundles\KeywordBundle\Controller\ObjectKeywordController();
$queryBuilder = $repository->createQueryBuilder('e');
$queryBuilder->andWhere('e.status=:status');
$queryBuilder->setParameter('status', 'public');
$queryBuilder->andWhere('e.displayTranslation = :displayTranslation');
$queryBuilder->setParameter('displayTranslation', 'true');
$queryBuilder->orderBy('e.publishedDate', 'DESC');
$query = $queryBuilder->getQuery();
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
if ($locale) {
$query->setHint(\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE, $locale);
}
$paginator = new Paginator($query);
$total_items = count($paginator);
$pages_count = (int) ceil($total_items / $page_row_count);
// now get one page's items:
$paginator
->getQuery()
->setFirstResult($page_row_count * ($current_page - 1)) // set the offset
->setMaxResults($page_row_count); // set the limit
我得到以下问题:
SELECT a0_.id AS id_0, t1_.content AS title_1, t2_.content AS sub_title_2, t3_.content AS announce_3, t4_.content AS author_4, t5_.content AS content_5, t6_.content AS source_6, a0_.creation_date AS creation_date_7, a0_.update_date AS update_date_8, a0_.published_date AS published_date_9, a0_.schedule_disable_date AS schedule_disable_date_10, a0_.schedule_publish_date AS schedule_publish_date_11, t7_.content AS seo_title_12, t8_.content AS seo_description_13, t9_.content AS keywords_as_text_14, t10_.content AS main_pic_description_15, t11_.content AS main_pic_title_16, t12_.content AS slug_17, t13_.content AS status_18, t14_.content AS display_translation_19, a0_.comments_enabled AS comments_enabled_20, t15_.content AS comments_count_21, a0_.main_pic AS main_pic_22, a0_.poll_id AS poll_id_23, a0_.attachment_id AS attachment_id_24, a0_.gallery_id AS gallery_id_25, a0_.created_by AS created_by_26, a0_.main_category_id AS main_category_id_27 FROM articles a0_ LEFT JOIN article_translations t1_ ON t1_.locale = 'bg' AND t1_.field = 'title' AND t1_.object_id = a0_.id LEFT JOIN article_translations t2_ ON t2_.locale = 'bg' AND t2_.field = 'subTitle' AND t2_.object_id = a0_.id LEFT JOIN article_translations t3_ ON t3_.locale = 'bg' AND t3_.field = 'announce' AND t3_.object_id = a0_.id LEFT JOIN article_translations t4_ ON t4_.locale = 'bg' AND t4_.field = 'author' AND t4_.object_id = a0_.id LEFT JOIN article_translations t5_ ON t5_.locale = 'bg' AND t5_.field = 'content' AND t5_.object_id = a0_.id LEFT JOIN article_translations t6_ ON t6_.locale = 'bg' AND t6_.field = 'source' AND t6_.object_id = a0_.id LEFT JOIN article_translations t7_ ON t7_.locale = 'bg' AND t7_.field = 'seoTitle' AND t7_.object_id = a0_.id LEFT JOIN article_translations t8_ ON t8_.locale = 'bg' AND t8_.field = 'seoDescription' AND t8_.object_id = a0_.id LEFT JOIN article_translations t9_ ON t9_.locale = 'bg' AND t9_.field = 'keywordsAsText' AND t9_.object_id = a0_.id LEFT JOIN article_translations t10_ ON t10_.locale = 'bg' AND t10_.field = 'mainPicDescription' AND t10_.object_id = a0_.id LEFT JOIN article_translations t11_ ON t11_.locale = 'bg' AND t11_.field = 'mainPicTitle' AND t11_.object_id = a0_.id LEFT JOIN article_translations t12_ ON t12_.locale = 'bg' AND t12_.field = 'slug' AND t12_.object_id = a0_.id LEFT JOIN article_translations t13_ ON t13_.locale = 'bg' AND t13_.field = 'status' AND t13_.object_id = a0_.id LEFT JOIN article_translations t14_ ON t14_.locale = 'bg' AND t14_.field = 'displayTranslation' AND t14_.object_id = a0_.id LEFT JOIN article_translations t15_ ON t15_.locale = 'bg' AND t15_.field = 'commentsCount' AND t15_.object_id = a0_.id WHERE t13_.content = 'public' AND t14_.content = 'true' AND a0_.id IN ('176448', '176447', '176446', '176444', '176442', '176441', '176440', '176437', '176436', '176435', '176434', '176424') ORDER BY a0_.published_date DESC;
并为每个对象提供如下查询:
SELECT t0.id AS id_1, t0.locale AS locale_2, t0.field AS field_3, t0.content AS content_4, t0.object_id AS object_id_5 FROM article_translations t0 WHERE t0.object_id = ?
如何避免这些额外的查询以及为什么学说不使用第一个的数据?
注意:所有额外查询都是在TranslatableListener类的函数postLoad中生成的。有一个参数$ skipOnLoad,它总是假的,看起来这是某种程度上的问题,但为什么会发生这种情况我不知道:)