2013-04-23 178 views
0

我正在用syfmony2框架構建我的第一個應用程序。 現在我堅持一點關於如何從我的數據庫中獲取數據。Symfony2/Doctrine關係映射

首先這裏我表(唯一重要的領域)

#客戶

CUSTOMER_ID | INT | AI | PK

#文章

的article_id | INT | AI | PK

number | 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到客戶是多到一(單向)關係

文章CustomerArticle是一個一對多(單向)關係

CustomerArticle條是多到一(裁研ectional)Relationship

在這一點上它是正確的嗎?

現在是否需要在每個 實體文件中進行此(4)關係映射?或者我只需要做一個方法,例如 客戶向CustomerArticle(一到多 - 單向)和 文章CustomerArticle(一到多 - 單向)

不幸的是,「一到五月,單向」是唯一一個沒有 正確在學說參考頁上的例子。

他們寫道: 「從主義的角度來看,它是簡單地映射爲一個單向多到很多,其中連接列上的一個獨特的約束強制一對多基數」

這是否意味着我只需要在頁面上的「單向多對多」部分進行映射?

很抱歉有很多問題。

我閱讀了大量的單證,但我不能回答這些問題我自己。

感謝您的任何幫助。

更新2013年4月26日

不幸的是我不能讓它甚至與Lighthart的幫助和閱讀文檔學說工作。

我認爲這是有益的給你關於我的表和代碼的更多細節。也許有人可以給我必要的答案,所以我最終理解它背後的概念。

我的一些示例表中的條目

Table: customer (PK: customer_id) 
+-------------+--------+----------+-------------------+------+-----------+ 
| customer_id | number | password | email    | salt | is_active | 
+-------------+--------+----------+-------------------+------+-----------+ 
| 1   | CU0001 | 43t9wef | [email protected] | test | 1   | 
| 2   | CU0002 | 32rk329 | [email protected] | 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表
  • 添加一個多對多的關係給客戶(和文章)實體

這是實體文件什麼樣子的此刻(無方法)

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」代碼,但它沒有幫助。

我的目標是什麼?

我從某些csv文件導入數據到表中: 「customer」,「article」以及當前不存在的表「customer_article」中。

在我的應用程序中,每個客戶都有一些引用他的文章。 因此該表將看起來像這樣

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

這不是一個店鋪或類似這樣的東西。要解釋這一點非常困難,因爲只有知道每個客戶都有未定義數量的相關文章纔是必要的。

現在,我必須能夠通過customer_id獲得所有與一位顧客相關的物品。 (看看我上面的起始帖子中的示例sql語句)

我希望你能幫助我。

非常感謝大家。

回答

1

這真的看起來像客戶和文章多對多。您要構建的實體是Customer.php和Article.php,您可以通過註釋在這些文件中指定多對多,或者根據您的偏好在doctrine.orm.yml中指定多對多。

主義將爲您製作中間表(customer_article)並對其進行管理。

你會使用DQL:

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

然後,你會處理文章爲實體,並調用article.getCustomer()用於與商品相關的客戶名單。

這是一個與SQL根本不同的範例,需要一些習慣。

+0

感謝您的反饋。 我有點困惑這是否意味着我必須刪除我的CustomerArticle實體並使用它創建的表? 您寫下了 「Doctrine將爲您創建中間表(customer_article)並對其進行管理。」 這是否意味着我在 Customer.php和Article.php中創建一個多對多的註釋,Article.php確保Doctrine將創建一個 表「customer_article」,而不必在CustomerArticle.php中指定它? 據我瞭解你的DQL-Example我也可以做它反之亦然 所有與用戶相關的文章? 這是真的不同的方法 - 謝謝 – Manuel 2013-04-24 07:24:05

+0

如果,並且只有如果您有其他屬性與多對多關聯,您將需要手動指定連接表。否則,你不需要它作爲一個實體。如果除了外鍵之外沒有其他字段,則應該刪除它並讓教條爲您處理。你正確地使用反向查詢'$ query = $ em-> createQuery(「SELECT c FROM Customer c JOIN c.article a」);'是獲取客戶列表所必需的。 – Lighthart 2013-04-24 13:46:02

+0

我無法得到它的工作。我延長我的第一篇文章,也許有助於理解這個問題。 – Manuel 2013-04-26 15:35:14

0

您的映射不好。您指定了連接表,但不指定反向連接列。嘗試:

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

另外,將主鍵映射到'id'以外的東西有點不尋常。

+0

這效果很好,謝謝!目前我並不完全理解爲什麼要使用「inverseJoinColumns」(因爲它在多對多雙向文檔中也缺少),但它是我可以搜索以獲取更多信息的關鍵字。還有一個問題:在「ManyToMany」符號中,inversedBy =「customers」缺失。Doku教條說:「雙向關係的擁有者必須通過使用inversedBy屬性來引用它的反面」非常感謝你幫助我。 – Manuel 2013-04-29 08:04:47

+0

InversedBy用於oneToMany或ManytoOne。在這些情況下,它存儲在數據庫中「多」一側的字段。 InversedBy允許你指定你想要的列名稱,如果你不喜歡默認的(類似於ManytoMany中的JoinColumns和InverseJoinColumns) – Lighthart 2013-04-29 13:55:48