cho*_*ise 6 php doctrine symfony
我正在玩Symfony2和Doctrine2.
我有一个具有唯一标题的实体,例如:
class listItem
{
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @orm:Column(type="string", length="255", unique="true")
* @assert:NotBlank()
*/
protected $title;
Run Code Online (Sandbox Code Playgroud)
现在我正在获取一个json并用这些项更新我的数据库:
$em = $this->get('doctrine.orm.entity_manager');
foreach($json->value->items as $item) {
$listItem = new ListItem();
$listItem->setTitle($item->title);
$em->persist($listItem);
}
$em->flush();
Run Code Online (Sandbox Code Playgroud)
第一次工作正常.但第二次我得到一个SQL错误(当然):Integrity constraint violation: 1062 Duplicate entry
有时我的json文件会更新,有些项目是新的,有些则不是.有没有办法告诉实体经理跳过重复的文件,只是插入新的文件?
什么是最好的方法呢?
谢谢你的帮助.如果不清楚,请发表评论
对我有用的是做这样的事情:
$uniqueness = $em->getRepository('ListItem')->checkUniqueness($item->title);
if(false == $uniqueness) {
continue;
}
$listItem = new ListItem();
$listItem->setTitle($item->title);
$em->persist($listItem);
$em->flush();
}
Run Code Online (Sandbox Code Playgroud)
checkUniqueness 是我的ListItem Repo中的一个方法,它检查标题是否已经在我的数据库中.
那太糟了.这是每个项目的2个数据库查询.这最终会导致大约85个数据库查询.
首先将所有当前标题检索到数组中,然后根据该数组中的当前标题检查插入标题如何
$existingTitles = $em->getRepository('ListItem')->getCurrentTitles();
foreach($json->value->items as $item) {
if (!in_array($item->title, $existingTitles)) {
$listItem = new ListItem();
$listItem->setTitle($item->title);
$em->persist($listItem);
}
}
$em->flush();
Run Code Online (Sandbox Code Playgroud)
getCurrentTitles() 需要添加到 ListItem Repo 中才能简单地返回标题数组。
这仅需要一个额外的数据库查询,但会花费更多的内存来将当前标题保存在数组中。如果 ListItem 的数据集非常大,则此方法可能会出现问题。
如果您每次要插入的项目数量不太大,您可以修改 getCurrentTitles() 函数来查询所有具有您尝试插入的标题的项目。这样,您将返回的 $existingTiles 的最大数量将是插入数据列表的大小。然后您可以按照上面的方式执行检查。
// getCurrentTitles() - $newTitles is array of all new titles you want to insert
return $qb->select('title')
->from('Table', 't')
->in('t.title = ', $newTitles)
->getArrayResult();
Run Code Online (Sandbox Code Playgroud)