每当我插入数据库中已存在的实体时,我都会收到错误,因为其中一个字段(email
)存在唯一约束。
所以我想检查它是否已经存在;如果没有,我插入它。
我的代码如下所示:
$q = Doctrine_Query::create()
->from('User u')
->where('u.email = ?', $email);
$object = $q->fetchOne();
if( ! is_object($object)) {
$user = new User();
$user-email = $email;
$user->save();
}
有更简单的方法吗?
答案 0 :(得分:8)
将您拥有的代码放入UserTable类的方法中,例如insertIfNotExists()
:
public function insertIfNotExists(User $user)
{
// Check if it exists first
$q = self::create("u")
->where("u.email = ?", $user->email)
->execute();
// Do we have any?
if ($q->count())
{
// Yes, return the existing one
return $q->getFirst();
}
// No, save and return the newly created one
$user->save();
return $user;
}
现在你可以调用方法,返回的对象将是现有记录(如果有的话),或者你刚刚创建的记录。
答案 1 :(得分:1)
在构建数据库支持的记录器时,我遇到了类似的问题。为防止警告疲劳,我为每条日志消息分配一个UID,这是其标识内容的散列,并使UID成为唯一密钥。
当然,这要求我确定是否已存在与该UID值匹配的记录(在我的情况下,我为该日志记录增加count
值并触及其updated_at
时间戳。 / p>
我最终在我的模型类中覆盖Doctrine_Record::save()
,与此类似(代码调整为与您的情况更相关):
/** Persists the changes made to this object and its relations into the
* database.
*
* @param $conn Doctrine_Connection
* @return void
*/
public function save( Doctrine_Connection $conn = null )
{
/* Invoke pre-save hooks. */
$this->invokeSaveHooks('pre', 'save');
/* Check to see if a duplicate object already exists. */
if( $existing = $this->getTable()->findDuplicate($this) )
{
/* Handle duplicate. In this case, we will return without saving. */
return;
}
parent::save($conn);
}
UserTable::findDuplicate()
看起来像这样:
/** Locates an existing record that matches the specified user's email (but
* without matching its PK value, if applicable).
*
* @param $user User
*
* @return User|bool
*/
public function findDuplicate( User $user )
{
$q =
$this->createQuery('u')
->andWhere('u.email = ?', $user->email)
->limit(1);
if( $user->exists() )
{
$q->andWhere('u.id != ?', $user->id);
}
return $q->fetchOne();
}
请注意,在模型中覆盖preSave()
而不是save()
可能是更好的方法。在我的情况下,我不得不等到执行预保存挂钩(使用Doctrine template that I had created设置UID),所以我不得不改写save()
。
答案 2 :(得分:-7)
您应该使用Memcached或Redis队列来检查项目是否存在。