学说中的多对多关系

时间:2009-12-08 17:32:39

标签: php mysql orm doctrine

我的系统上有一些表格如下:

news
--id
--title
--content

video
--id
--title
--url

album
--id
--title

现在,我需要与这些表进行多对多的关系,但是要灵活。我用以下结构创建了一个名为'links'的表:

links
--parent_entity (example: news)
--parent_id   (example: 5)
--child_entity (exmaple: video)
--child_id (example: 2)

如何使用Doctrine进行映射?

3 个答案:

答案 0 :(得分:2)

这是不可能的,因为您无法进行正确的连接。在这种情况下的连接将取决于parent_entity和child_entity中的值(即,每行可能需要连接到不同的表)。另外,学说将如何知道哪种记录类型能够水合(即,因为它取决于实体类型)。

你可以通过在连接上使用WITH子句来拉掉这样的东西(尽管它会很奇怪)。例如,在新闻模型的setUp()方法中,您可以执行以下操作:

$this->hasMany('Links as NewsVideoLinks', array('local' => 'id', 'foreign' => 'parent_id'));

在您的Links模型的设置中:

$this->hasMany('Videos as videos', array('local' => 'child_id', 'foreign' => 'id'));

您需要在Links模型中定义连接的所有组合。我的意思是,你需要告诉它它有很多新闻和专辑,同时使用child_id和parent_id。

然后在您的查询中,您需要执行以下操作:

$query = Doctrine_Query::create();
$query->from('News n');
$query->innerJoin("n.NewsVideoLinks as links WITH parent_entity = 'news'");
$query->innerJoin("links.Videos as vids WITH child_entity = 'videos'");
$results = $query->execute();

正如您所看到的,这非常麻烦。我强烈建议为每个关系创建连接表。您可以通过加入每个联接表来获得所需内容。

答案 1 :(得分:0)

Doctrine的documentation非常好。我不太清楚你对“灵活”的意思,但这里是Doctrine 1.2版的Many-To-Many关系的yaml配置示例。

---
User:
  columns:
    id:
      type: integer(4)
      autoincrement: true
      primary: true
    username:
      type: string(255)
    password:
      type: string(255)
  attributes:
    export: all
    validate: true

Group:
  tableName: group_table
  columns:
    id:
      type: integer(4)
      autoincrement: true
      primary: true
    name:
      type: string(255)
  relations:
    Users:
      foreignAlias: Groups
      class: User
      refClass: GroupUser

GroupUser:
  columns:
    group_id:
      type: integer(4)
      primary: true
    user_id:
      type: integer(4)
      primary: true
  relations:
    Group:
      foreignAlias: GroupUsers
    User:
      foreignAlias: GroupUsers

答案 2 :(得分:0)

如果我正确理解您的数据库布局,则“parent_entity”和“child_entity”表示您希望将ID链接到的表。

这在技术上是一个不正确的数据库结构(请参阅database normalization),因为您无法将这些列映射到任何其他单个表列。基本上,您无法使用你的id列现在是不明确的。

我认为你必须重新思考你的数据库逻辑,然后才能更容易地编写代码。