Symfony2 / Doctrine Relationship Mapping

时间:2013-04-23 13:25:14

标签: mysql symfony doctrine entity-relationship

我正在使用syfmony2框架构建我的第一个应用程序。 现在我稍微谈谈如何从我的数据库中获取数据。

首先是我的表格(仅限重要字段)

#customer

customer_id | INT | AI | PK

#article

article_id | INT | AI | PK

号码VARCHAR

#customer_article (两个字段构建PK)

customer_id | INT | PK

article_id | INT | PK

现在我想执行一个简单的查询:

SELECT 
   ca.article_id, a.number 
FROM 
   customer_article AS ca
LEFT JOIN 
   article AS a ON a.article_id = ca.article_id
WHERE 
   ca.customer_id = {customer_id}

据我所知,文档最好的方法是 在我的实体php文件中建立关系映射。

Customer.php

Article.php

CustomerArticle.php

但我很困惑该做什么以及朝哪个方向努力。 (http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html

在我看来,这必须是正确的关系

客户到CustomerArticle是一对多(单向)关系

CustomerArticle to Customer是一对多(单向)关系

文章到CustomerArticle是一对多(单向)关系

CustomerArticle to Article是多对一(单向)关系

此时是否正确?

现在有必要在每个人中进行这个(4)关系映射 实体文件?或者我只需要以一种方式来做,例如 客户到CustomerArticle(一对多 - 单向)和 文章到客户文章(一对多 - 单向)

不幸的是,“One-To-May,Unidirectional”是唯一没有的 关于学说参考页面的正确例子。

他们写道: “从Doctrine的角度来看,它被简单地映射为单向多对多,其中一个连接列的唯一约束强制执行一对多基数”

这是否意味着我只需要在页面的“单向多对多”部分进行映射?

对很多问题感到抱歉。

我在文件中看了很多,但我不能为自己回答这些问题。

感谢您的帮助。

更新2013年4月26日

不幸的是,即使在Lighthart的帮助和阅读Doctrine文档的情况下,我也无法工作。

我认为向您提供有关我的表格和代码的更多详细信息会很有帮助。也许有人可以给我基本的答案,所以我最终理解它背后的概念。

包含一些示例条目的我的表格

Table: customer (PK: customer_id)
+-------------+--------+----------+-------------------+------+-----------+
| customer_id | number | password | email             | salt | is_active |
+-------------+--------+----------+-------------------+------+-----------+
| 1           | CU0001 | 43t9wef  | test@example.com  | test | 1         |
| 2           | CU0002 | 32rk329  | test2@example.com | test | 1         |
+-------------+--------+----------+-------------------+------+-----------+

Table: article (PK: article_id)
+-------------+---------+
| article_id  | number  |
+-------------+---------+
| 1           | TEST-01 |
| 2           | TEST-02 |
| 3           | TEST-03 |
| 4           | TEST-04 |
| 5           | TEST-05 |
+-------------+---------+

自我第一次发帖以来我做了什么?

  • 删除CustomerArticle.php
  • 删除customer_article表
  • 向客户(和文章)实体添加ManyToMany关系

这就是实时文件此刻的样子(没有方法)

Customer.php

<?php
namespace Test\ExampleBundle\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="customer")
 */
class Customer implements UserInterface
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $customer_id;

/**
 * @ORM\ManyToMany(targetEntity="Article", inversedBy="customers")
 * @ORM\JoinTable(name="customer_article",
 *  joinColumns={ @ORM\JoinColumn(name="customer_id", referencedColumnName="customer_id" ) }
 * )
 */
private $articles;

/**
 * @ORM\Column(type="string", length=255, nullable=false, unique=true)
 */
protected $number;

/**
 * @ORM\Column(type="string", length=255, nullable=false)
 */
protected $password;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
protected $email;

/**
 * @ORM\Column(type="string", length=255)
 */
protected  $salt;

/**
 * @ORM\Column(name="is_active", type="boolean")
 *
 */
protected  $isActive;

// ... methods
}

Article.php

<?php
namespace Test\ExampleBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="article")
 */
class Article
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $article_id;

/**
 * @ORM\ManyToMany(targetEntity="Customer", mappedBy="articles")
 */
private $customers;

/**
 * @ORM\Column(type="string", length=255, nullable=false, unique=true)
 */
protected $number;

// ... methods
}

当我尝试执行时:

php app/console doctrine:schema:update --force

我收到以下消息

[Doctrine\ORM\ORMException]
Column name `id` referenced for relation from    Test\ExampleBundleBundle\Entity\Customer towards Test\ExampleBundleBundle\Entity\Article does not exist.

我不知道为什么教义要使用列名“id”。我读了一些关于这个错误的内容并添加了“JoinColumns”-Code,但它没有帮助。

我的目标是什么?

我将一些csv文件中的数据导入表中: “客户”,“文章”以及当前不存在的表“customer_article”。

在我的应用程序中,每个客户都有一些引用他的文章。 所以表格看起来像这样

customer_article
+-------------+------------+
| customer_id | article_id |
+-------------+------------+
| 1           | 1          |
| 1           | 2          |
| 1           | 5          |
| 2           | 2          |
| 2           | 5          |
+-------------+------------+

这不是商店或类似的东西。这很难解释,所以首先只需知道每个客户都有不确定数量的相关文章。

现在,我必须能够使用customer_id获得与一位客户相关的所有文章。 (在上面的开头文章中查看我的示例sql语句)

我希望你能帮助我。

非常感谢大家。

2 个答案:

答案 0 :(得分:1)

对于客户和文章来说,这看起来像是双向的。您要构建的实体是Customer.php和Article.php,您可以通过注释在这些文件中指定多对多,或者根据您的偏好在doctrine.orm.yml中指定。

Doctrine将为您制作中间表(customer_article)并对其进行管理。

你会使用DQL:

$query = $em->createQuery("SELECT a FROM Article a JOIN a.customer c");
$users = $query->getResult();

然后,您将文章作为实体处理,并调用article.getCustomer()以获取与文章关联的客户列表。

这是一个与SQL完全不同的范例,需要一些时间来习惯。

答案 1 :(得分:0)

您的映射很糟糕。您指定了jointable但未指定反向连接列。尝试:

 /**
  * @ManyToMany(targetEntity="Article")
  * @JoinTable(name="customer_article",
  *      joinColumns={@JoinColumn(name="Customer_id", referencedColumnName="cusomter_id")},
  *      inverseJoinColumns={@JoinColumn(name="Article_id", referencedColumnName="article_id")}
  *      )
  */

顺便说一下,将主键映射到“id”之外的其他内容有点不寻常。