Doctrine 在插入之前,请检查数据库中是否已存在实体
每当我插入数据库中已经存在的实体时,我都会收到一个错误,因为其中一个字段(Doctrine 在插入之前,请检查数据库中是否已存在实体,doctrine,unique-constraint,Doctrine,Unique Constraint,每当我插入数据库中已经存在的实体时,我都会收到一个错误,因为其中一个字段(email)上存在唯一约束 所以我想检查它是否已经存在;如果没有,我将其插入 我的代码如下所示: $q = Doctrine_Query::create() ->from('User u') ->where('u.email = ?', $email); $object = $q->fetchOne(); if( ! is_object($object)) { $u
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();
}
/** 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();
}
有更简单的方法吗?将您的代码放入UserTable类中的方法中,例如
insertIfNotExists()
:
现在您可以调用该方法,返回的对象将是现有记录(如果有)或您刚刚创建的记录。将您拥有的代码放入UserTable类中的方法中,例如
insertIfNotExists()
:
现在您可以调用该方法,返回的对象将是现有记录(如果有)或您刚刚创建的记录。在构建数据库支持的记录器时,我遇到了类似的问题。为了防止警告疲劳,我为每个日志消息分配了一个UID,它是其标识内容的散列,并使UID成为唯一的密钥 当然,这需要我确定是否已经存在与该UID值匹配的记录(在我的例子中,我为该日志记录增加一个
count
值,并在时间戳处触摸其updated_)
我最终在我的模型类中重写了Doctrine\u Record::save()
,与此类似(代码调整为与您的情况更相关):
UserTable::findDuplicate()
如下所示:
$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();
}
/** 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()
更好。在我的例子中,我必须等到预保存钩子执行(UID是使用a设置的),所以我不得不覆盖save()
。在构建数据库支持的记录器时,我也面临类似的问题。为了防止警告疲劳,我为每个日志消息分配了一个UID,它是其标识内容的散列,并使UID成为唯一的密钥
当然,这需要我确定是否已经存在与该UID值匹配的记录(在我的例子中,我为该日志记录增加一个count
值,并在
时间戳处触摸其updated_)
我最终在我的模型类中重写了Doctrine\u Record::save()
,与此类似(代码调整为与您的情况更相关):
UserTable::findDuplicate()
如下所示:
$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();
}
/** 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()
更好。在我的例子中,我必须等到预保存挂钩执行(UID是使用a设置的),所以我必须覆盖save()
相反。您应该使用Memcached或Redis队列来检查项目是否存在。您应该使用Memcached或Redis队列来检查项目是否存在。请在您的答案中添加一些解释,以便其他人可以从中学习-为什么这是一个好主意?如果另一个进程将数据添加到数据库中,而不是缓存层,该怎么办?要进行简单的“查找”,最好使用诸如memcached或Redis之类的缓存引擎,因为它更快、更具可扩展性。请对您的答案添加一些解释,以便其他人可以从中学习-为什么这是一个好主意?如果另一个进程向数据库中添加数据,而不是向缓存层中添加数据,该怎么办?要进行简单的“查找”,最好使用诸如memcached或Redis之类的缓存引擎,因为它更快、更具可扩展性。