在Doctrine中更新多对多关系

时间:2011-05-17 15:45:24

标签: php database zend-framework doctrine many-to-many

我有文章类别关系,我想在必要时更新关系。这意味着,在文章中添加或删除所需的类别。我使用Doctrine 1.2的php(ZF)设置。在YAML中,配置看起来(简化)如下:

Article:
  columns:
    id: bigint(10)

Category:
  columns:
    id: bigint (10)
  relations:
    articles:
      foreignAlias: categories
      class: Article
      refClass: CategoryArticle

CategoryArticle:
  columns:
    category_id: bigint (10)
    article_id: bigint (10)
  relations:
    category:
      class: Category
      foreignAlias: categoryArticle
    article:
      class: Article
      foreignAlias: categoryArticle

我有一篇持久的$文章,其中所有旧类别都可用。通过POST请求,我得到了一个类别ID列表,它应该是新的。到目前为止我有这个:

$oldCategories = array();
foreach ($article->categories as $cat) {
    $oldCategories[] = $cat->id;
}
$newCategories = $form->getValue('categories');

$diffRemove = array_diff($oldCategories, $newCategories);
$diffAdd    = array_diff($newCategories, $oldCategories);
foreach ($diffRemove as $id) {
    // Remove all the categories $id from article [1]
}
foreach ($diffAdd as $id) {
    // Add all the categories $id to article [2]
}

我的问题是[1]和[2]。添加和删​​除多个关系的最佳性能是什么?

1 个答案:

答案 0 :(得分:4)

删除

在SQL中删除集合的最有效方法是使用单个sql语句并设置一些条件,例如

delete from Products where id>3

它使用索引,分区等

有一种方法可以使用Doctrine 1.2实现该性能值 - 使用DQL DELETE语句。如文档中所示,以下查询转换为上述SQL:

$q = Doctrine_Query::create()
    ->delete('Products p')
    ->where('p.id > 3');

在您的情况下,您可以使用

等优化删除
$q = Doctrine_Query::create()
    ->delete('CategoryArticle ca')
    ->where('ca.article_id=?', $article_id)
    ->andWhereIn('ca.category_id', $diffRemove);

此代码应生成如下内容:

delete from CategoryArticle 
where article_id = $article_id and category_id in ($diffremove)

插入

通过插入,您可以使用CategoryArticle实体。使用Doctrine执行此操作的最有效方法是构建实体集合,然后保存该集合:

$collection = new Doctrine_Collection('CategoryArticle');
foreach ($diffAdd as $id){
    $ca = new CategoryArticle();
    $ca->category = $id;
    $ca->article = $article_id;
    $collection[] = $ca;
}

$collection->save();