[英]Update a many-to-many relationship in Doctrine
I have an article-category relationship and I'd like to update the relationship when necessary. 我有一个文章类别关系,我想在必要时更新该关系。 That means, adding or removing the desired categories from an article.
就是说,在文章中添加或删除所需的类别。 I use a php (ZF) setup with Doctrine 1.2.
我在Doctrine 1.2中使用php(ZF)设置。 In YAML, the config looks (simplified) like this:
在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
I have a persisted $article where all old categories are available. 我有一个坚持的文章,其中所有旧类别均可用。 With a POST request I get a list of category ids which should be the new ones.
通过POST请求,我得到了应该为新类别ID的列表。 I have this so far:
到目前为止,我有:
$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]
}
My question is about [1] and [2]. 我的问题是关于[1]和[2]。 What is the best performance to add and remove a many:many relationship?
添加和删除多对多关系的最佳性能是什么?
The most efficient way of deleting en masse in SQL is using single sql statement with some conditions set, something like 删除SQL中最有效的方法是使用设置了某些条件的单个sql语句,例如
delete from Products where id>3
It make use of indexes, partitioning, etc. 它利用索引,分区等。
There is a way to achieve that value of performance using Doctrine 1.2 - using DQL DELETE statements. 有一种方法可以使用Doctrine 1.2实现该性能值-使用DQL DELETE语句。 As shown in documentation, the following query transforms into the above SQL:
如文档所示,以下查询将转换为上述SQL:
$q = Doctrine_Query::create()
->delete('Products p')
->where('p.id > 3');
In your case, you could optimize deletion with something like 在您的情况下,您可以使用以下方式优化删除操作:
$q = Doctrine_Query::create()
->delete('CategoryArticle ca')
->where('ca.article_id=?', $article_id)
->andWhereIn('ca.category_id', $diffRemove);
This code should generate something like: 此代码应生成如下内容:
delete from CategoryArticle
where article_id = $article_id and category_id in ($diffremove)
With insertion you could use CategoryArticle
entity. 插入后,您可以使用
CategoryArticle
实体。 The most effective way to do that with Doctrine is to build up a collection of Entities and than save that collecion: 使用Doctrine进行此操作最有效的方法是建立一个实体集合,然后保存该集合:
$collection = new Doctrine_Collection('CategoryArticle');
foreach ($diffAdd as $id){
$ca = new CategoryArticle();
$ca->category = $id;
$ca->article = $article_id;
$collection[] = $ca;
}
$collection->save();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.