Doctrine 多对多内部连接

Doctrine Many To Many Inner Join

我正在尝试与 Doctrine 和 symfony 建立多对多关系。 我是 Doctrine 和 Symfony 的新手。我来自Zend框架。

我创建了 3 个 table: Post、Post类别和交汇点 table PostToCategory,如下所示。

我的目标是进行内部联接并获取每个 post 的类别。 这是我到目前为止所做的:

//CMS/GBundle/Entity/PostContent

class PostContent
{

    /**
     * @ORM\ManyToMany(targetEntity="CMS\GBundle\Entity\PostCategory", inversedBy="posts")
     * @ORM\JoinTable(name="post_to_category")
     */
    protected $categories;

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

//CMS/GBundle/Entity/PostCategory

class PostCategory
{

    /**
     * @ORM\ManyToMany(targetEntity="CMS\GBundle\Entity\PostContent", mappedBy="categories")
     */
    protected $posts;

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

我现在想创建 returns 我加入数据 Post->Post 类别的功能。

我应该在哪里创建函数?在 PostToCategory 存储库中?或者别的地方 ?我的查询应该是什么样的?

我尝试了很多选项,我在 Stack 上通过了所有可能的问题,但我无法完成..

提前致谢!

更新:

这是我在 Post 内容存储库上执行 findAll 方法时得到的结果。

您可以为您的实体创建存储库 class,例如:

CMS/GBundle/Repository/PostContentRepository.php

<?php

namespace CMS\GBundle\Repository;

use Doctrine\ORM\EntityRepository;

class PostContentRepository extends EntityRepository
{
    public function getPostsWithCategories()
    {
        $qb = $this->createQueryBuilder('post_content')
            ->select(['post_content', 'post_categories'])
            ->join('post_content.categories', 'post_categories')
        ;

        return $qb->getQuery()->getResult();
    }
}

CMS/GBundle/Entity/PostContent.php

<?php

namespace CMS\GBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="CMS\GBundle\Repository\PostContentRepository")
 */
class PostContent
{
    /* Your entity properties and methods */
}

然后你可以在任何地方使用它。例如,在控制器中:

<?php

namespace CMS\GBundle\Controller;

use ;

class SomeController extends Controller
{
    public function someAction()
    {
        $posts = $this->getDoctrine()
            ->getManager()
            ->getRepository('CMSGBundle:PostContent')
            ->getPostsWithCategories()
        ;

        /* Your logic */
    }
}

建立关系的首选方法是像您一样创建您的实体,然后 运行 一个控制台命令以使用一些 getter 和 setter 扩展您的实体:

$ bin/console doctrine:generate:entities AppBundle

然后让 doctrine 创建您的表格:

$ bin/console doctrine:schema:update --force

现在一切就绪,您必须在数据库表中填充一些数据。

$category = new Category();
$categroy->setName('PHP Programming');
$em->persist($category);

$post = new Post();
$post->setTitle('My first Blogpost');
$post->addCategory($category);
$em->persist($post);

$em->flush();

之后就可以搞定了。我只是举个例子

public function indexAction($id)
{
    $em = $this->getDoctrine()->getManager();
    $category= $em->getRepository('AppBundle:PostCategory')->find($id);

    // test
    foreach($category->getPosts() as $post)
    {
        echo $post->getTitle() . '<br>';
    }
}

要立即加载所有帖子而不是延迟加载,我建议在 CategoryRepository class 中编写您自己的查询并将 find() 方法名称更改为您自己的方法名称。

按照 Frankbeen 的建议,我创建了自定义查询:

public function getPostCategories() {

    $data = $this->createQueryBuilder('c')
        ->select('c.id, pc.name')
        ->innerJoin('CMSGBundle:PostToCategory', 'ptc', 'WITH', 'ptc.postId = c.id')
        ->innerJoin('CMSGBundle:PostCategory', 'pc', 'WITH', 'ptc.categoryId = pc.id')
        ->getQuery()
        ->getArrayResult();

    return $data;

}

在上面的方法中,我只获取与 post_to_category_post_id 类别名称相关的 post.id

在控制器中,我生成了两个查询,一个是获取所有帖子,第二个是使用 getPostCategories 方法获取数据。

控制器:

$em = $this->getDoctrine()->getManager();

    $posts = $em->getRepository('CMSGBundle:PostContent')->findAll();
    $postCategories = $em->getRepository('CMSGBundle:PostContent')->getPostCategories();

查看:

{% for post in posts %}
   {% for category in categories %}
      {% if category.id == post.id %}

         {{ category.name }}       

      {% endif %}
   {% endfor %}
{% endfor %}

我知道这不是最好的解决方案,如果有人可以建议我缩小相同的代码或如何更好地编写代码,我将不胜感激!