简体   繁体   English

多对多内在学说

[英]Doctrine Many To Many Inner Join

I'm trying to get manyToMany relationship with Doctrine and symfony. 我正在尝试与Doctrine和symfony建立多对多关系。 I'm new at Doctrine and Symfony. 我是Doctrine和Symfony的新手。 I came from Zend framework. 我来自Zend框架。

I've created the 3 tables: Post, PostCategory and junction table PostToCategory as you can see below. 我创建了3个表:Post,PostCategory和联结表PostToCategory,如下所示。

表格示例

My goal is to do inner join and to get for every post its categories. 我的目标是进行内部联接并获取每个帖子的类别。 This is what I've done so far: 到目前为止,这是我所做的:

//CMS/GBundle/Entity/PostContent // 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 // CMS / GBundle / Entity / PostCategory

class PostCategory
{

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

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

I would like now to create function that returns me joined data Post->PostCategories. 我现在想创建一个函数,该函数返回我加入的数据Post-> PostCategories。

Where should I create function ? 我应该在哪里创建函数? in PostToCategory Repository ? 在PostToCategory存储库中? or somewhere else ? 或者别的地方 ? How should my query look like ? 我的查询应如何显示?

I've tried a lot of options and I passed all the possible questions on Stack but I could not get it done.. 我尝试了很多选项,并在Stack上传递了所有可能的问题,但我无法完成。

Thanks in advance! 提前致谢!

Update: 更新:

这是我在findAll时得到的

This is what i get when i do findAll method on PostContent repository. 这是我在PostContent存储库上执行findAll方法时得到的。

You can create repository class for your entity, for example: 您可以为您的实体创建存储库类,例如:

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 */
}

And then you can use it in anywhere. 然后,您可以在任何地方使用它。 For example, in the controller: 例如,在控制器中:

<?php

namespace CMS\GBundle\Controller;

use ;

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

        /* Your logic */
    }
}

The preferred way to make a relationship is to create your entities like you did, then run a console command to extend your entity with some getters and setters: 建立关系的首选方法是像创建实体一样创建实体,然后运行控制台命令以使用一些getter和setter扩展实体:

$ bin/console doctrine:generate:entities AppBundle

and then let doctrine create your tables: 然后让主义创建您的表:

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

Now that is everything ready you have to fill some data in your database tables. 现在已经准备就绪,您必须在数据库表中填充一些数据。

$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();

After that can get it out. 之后就可以解决了。 I just give you an example 我举一个例子

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>';
    }
}

To load all the posts immediately instead of lazy loading i suggest to write your own query in the CategoryRepository class and change the find() method-name for your own method-name. 为了立即加载所有帖子而不是延迟加载,我建议在CategoryRepository类中编写您自己的查询,然后将find()方法名更改为您自己的方法名。

As Frankbeen advised me i created my custom query: 如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;

}

In Method above I'm fetching just post.id that is related to post_to_category_post_id category name 在上面的方法中,我只提取与post_to_category_post_id类别名称相关的post.id

In controller I generate two queries one to fetch all Posts second to fetch data using getPostCategories method. 在控制器中,我生成两个查询,一个查询以获取所有Post,然后使用getPostCategories方法获取数据。

Controller: 控制器:

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

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

View: 视图:

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

         {{ category.name }}       

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

I know that this is not the best solution and please if anyone can suggest me with minifing same code or how to write it better I will be grateful! 我知道这不是最好的解决方案,如果有人可以建议我尽量减少相同的代码或如何更好地编写代码,我将不胜感激!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM