多对多学说symfony

Many to Many doctrine symfony

我有问题。我的问题是这样的。

有一个表:产品,类别,products_categories

    Product
+----+--------------------------+
| id | title                    |
+----+--------------------------+
|  1 | Product 1                |
|  2 | Product 2                |
+----+--------------------------+

    Categries
+----+----------------------+----------+
| id | title                | slug     |
+----+----------------------+----------+
|  1 | Categories 1         | cat1     |
|  2 | Categories 2         | cat2     |
|  3 | Categories 3         | cat3     |
+----+----------------------+----------+

    Produts_Categories
+----------+---------------+
| product_id | category_id |
+----------+---------------+
|        1 |        3      |
|        2 |        3      |
|        1 |        1      |
+----------+---------------+

我需要这样做:

  1. 从类别 id 中获取产品
  2. 获取类别
  3. 的所有产品

我的产品实体

namespace ProductBundle\Entity;

use AppBundle\AppBundle;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\User;
use AppBundle\Entity\Categories;

/**
 * Product
 *
 * @ORM\Table(name="product")
 * @ORM\Entity(repositoryClass="ProductBundle\Repository\ProductRepository")
 */
class Product
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 *
 * @var ArrayCollection $categories
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Categories")
 * @ORM\JoinTable(name="product_categories",
 *      joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
 *      )
 */
private $categories;

/**
 * @var int
 *
 * @ORM\Column(name="user_id", type="integer")
 */
private $userId;

/**
 *
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

/**
 * @var string
 *
 * @ORM\Column(name="title", type="string", length=255)
 */
private $title;

/**
 * @var string
 *
 * @ORM\Column(name="description", type="text")
 */
private $description;

/**
 * @var string
 *
 * @ORM\Column(name="slug", type="string", length=255)
 */
private $slug;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="created_at", type="datetime")
 */
private $createdAt;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="updated_at", type="datetime")
 */
private $updatedAt;

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


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set userId
 *
 * @param integer $userId
 * @return Product
 */
public function setUserId($userId)
{
    $this->userId = $userId;

    return $this;
}

/**
 * Get userId
 *
 * @return integer 
 */
public function getUserId()
{
    return $this->userId;
}

/**
 * Set title
 *
 * @param string $title
 * @return Product
 */
public function setTitle($title)
{
    $this->title = $title;

    return $this;
}

/**
 * Get title
 *
 * @return string 
 */
public function getTitle()
{
    return $this->title;
}

/**
 * Set description
 *
 * @param string $description
 * @return Product
 */
public function setDescription($description)
{
    $this->description = $description;

    return $this;
}

/**
 * Get description
 *
 * @return string 
 */
public function getDescription()
{
    return $this->description;
}

/**
 * Set slug
 *
 * @param string $slug
 * @return Product
 */
public function setSlug($slug)
{
    $this->slug = $slug;

    return $this;
}

/**
 * Get slug
 *
 * @return string
 */
public function getSlug()
{
    return $this->slug;
}

/**
 * Set createdAt
 *
 * @param \DateTime $createdAt
 * @return Product
 */
public function setCreatedAt($createdAt)
{
    $this->createdAt = $createdAt;

    return $this;
}

/**
 * Get createdAt
 *
 * @return \DateTime 
 */
public function getCreatedAt()
{
    return $this->createdAt;
}

/**
 * Set updatedAt
 *
 * @param \DateTime $updatedAt
 * @return Product
 */
public function setUpdatedAt($updatedAt)
{
    $this->updatedAt = $updatedAt;

    return $this;
}

/**
 * Get updatedAt
 *
 * @return \DateTime 
 */
public function getUpdatedAt()
{
    return $this->updatedAt;
}

/**
 * @return User
 *
 */
public function getUser()
{
    return $this->user;
}

/**
 * @param User $user
 */
public function setUser(\AppBundle\Entity\User $user)
{
    $this->user = $user;
}

/**
 * Add categories
 *
 * @param \AppBundle\Entity\Categories $categories
 * @return Product
 */
public function addCategory(\AppBundle\Entity\Categories $categories)
{
    $this->categories[] = $categories;

    return $this;
}

/**
 * Remove categories
 *
 * @param \AppBundle\Entity\Categories $categories
 */
public function removeCategory(\AppBundle\Entity\Categories $categories)
{
    $this->categories->removeElement($categories);
}

/**
 * Get categories
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getCategories()
{
    return $this->categories;
}
}

我的类别实体

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Categories
 *
 * @ORM\Table(name="categories")
 *    @ORM\Entity(repositoryClass="AppBundle\Repository\CategoriesRepository")
 */
class Categories
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var int
 *
 * @ORM\Column(name="parent", type="integer")
 */
private $parent;

/**
 * @var int
 *
 * @ORM\Column(name="pos", type="integer")
 */
private $pos;

/**
 * @var string
 *
 * @ORM\Column(name="title", type="string", length=255)
 */
private $title;

/**
 * @var string
 *
 * @ORM\Column(name="slug", type="string", length=255)
 */
private $slug;


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set parent
 *
 * @param integer $parent
 * @return Categories
 */
public function setParent($parent)
{
    $this->parent = $parent;

    return $this;
}

/**
 * Get parent
 *
 * @return integer
 */
public function getParent()
{
    return $this->parent;
}

/**
 * Set pos
 *
 * @param integer $pos
 * @return Categories
 */
public function setPos($pos)
{
    $this->pos = $pos;

    return $this;
}

/**
 * Get parent
 *
 * @return integer
 */
public function getPos()
{
    return $this->pos;
}

/**
 * Set title
 *
 * @param string $title
 * @return Categories
 */
public function setTitle($title)
{
    $this->title = $title;

    return $this;
}

/**
 * Get title
 *
 * @return string 
 */
public function getTitle()
{
    return $this->title;
}

/**
 * Set slug
 *
 * @param string $slug
 * @return Categories
 */
public function setSlug($slug)
{
    $this->slug = $slug;

    return $this;
}

/**
 * Get slug
 *
 * @return string 
 */
public function getSlug()
{
    return $this->slug;
}
}

产品控制器

$em = $this->container->get('doctrine')->getManager();
$repository = $em->getRepository('ProductBundle:Product');
$products = $repository
->findAll();

但是没用。我明白了:

array:2 [▼
  0 => Product {#675 ▼
    -id: 1
    -categories: PersistentCollection {#676 ▼
      -snapshot: []
      -owner: Product {#675}
      -association: array:19 [ …19]
      -em: EntityManager {#574 …10}
      -backRefFieldName: null
      -typeClass: ClassMetadata {#583 …}
      -isDirty: false
      -initialized: false
      -coll: ArrayCollection {#677 ▶}
    }
    -userId: 1
    -user: User {#696 ▶}
    -title: "hjhkhk"
    -description: "hjhkjhkjh"
    -slug: "hjhkjhkj"
    -createdAt: DateTime {#672 ▶}
    -updatedAt: DateTime {#673 ▶}
  }
  1 => Product {#693 ▶}
]

您可以在存储库中使用您自己的逻辑执行您自己的请求(因为您似乎不太清楚您到底想要什么),例如:

public function findProducts() {
    $qb = $this->createQueryBuilder('p');
    $qb ->leftJoin('p.categories', 'cat');
    return $qb->getQuery()->getArrayResult();
}

第一种方法:

public function findProductsByCategory($categoryId) {
    $qb = $this->createQueryBuilder('p');
    $qb->select('p, cat')
        ->leftJoin('p.categories', 'cat')
        ->where('cat.id = :catId')
        ->setParameter('catId', $categoryId);
    return $qb->getQuery()->getResult();
}

此查询将为给定类别 return 产品。如果您想接收每个产品的类别,则必须遍历产品并获取每个产品的类别。

第二种方法:

public function getProductsWithCategories() {
    $qb = $this->createQueryBuilder('p');
    $qb->select('p, cat')
        ->leftJoin('p.categories', 'cat');
    return $qb->getQuery()->getResult();
}

此查询将 return 所有具有联合类别的产品。现在你必须在代码中过滤掉你感兴趣的那些产品。

区别:

在第一种方法中,您将在询问每个产品的类别时发送查询。

在第二种方法中,代码负责过滤产品。所以基本上这取决于你是想要数据库还是代码来处理更多的负载。