我是阿北,Yii学习社群正在搞技术文竞赛(获胜者送VIP权限),邀请你参加。 另外我的订阅号送书中,看详情
发布于 3个月前

[2.0.14] yii2数据库操作新增了一个好用的upsert

作为2.0分支的最后一个功能增强版本,v2.0.14对数据库和AR改动很多,upsert就是其中一项。

Upsert是一种原子操作,如果它们不存在(匹配唯一约束),则将行插入到数据库表中,或者在它们执行时更新它们,看着有点懵,其实这是非常常见的一种场景,看下面的题目

alt

有一张数据表share,要求是插入数据时候如果url已经存在则更新期updated_at字段为最新,否则新建这条记录。

我们可以分析出来,如果upsert起作用,数据表中最少要有一条唯一性约束,否则没有比较哇。

接下来我们插入一组数据

如果是之前的思路我们先要根据url进行查询,如果不存在则新建否则就更新,有了upsert,这一期简单了。

$conn = Yii::$app->db;
$conn->createCommand()->upsert("share",[
    'title'=>'百度',
    'url'=>'http://baidu.com',
    'created_at'=>time(),
    'updated_at'=>time(),
],['updated_at'=>time()])->execute();

一条语句就搞定了。

public function upsert($table, $insertColumns, $updateColumns = true, $params = [])

参数说明

  • $table 要操作的数据表
  • $insertColumns 插入的数据
  • $updateColumns 更新的数据
  • $params 绑定的参数

参数有一些特别的用法,比如我们先说$updateColumns,它可以是一个数组,内含要变化的字段值。

它也可以是true,代表如果存在也按照$insertColumns的内容进行更新

$conn->createCommand()->upsert("share",[
    'title'=>'百度',
    'url'=>'http://baidu.com',
    'created_at'=>time(),
    'updated_at'=>time(),
],true)->execute();

当然你也可以将$updateColumns设置为false

$conn->createCommand()->upsert("share",[
    'title'=>'百度',
    'url'=>'http://baidu.com',
    'created_at'=>time(),
    'updated_at'=>time(),
],false)->execute();

这很显然,即便已经存在,也不进行任何的更新。

接下来我们再回头说一下$insertColumns参数,$insertColumns接收一个数组或一个Query的对象,数组我们已经说明过了,接下来说说Query的对象形式。

$conn = Yii::$app->db;
$conn->createCommand()->upsert("share",XXX::find()->select(['xxx'])->where(['xxxx']),['updated_at'=>time()])->execute();

小结

想不到在2.0分支的最后一个功能版本上,upsert终于被支持了。

o( ̄▽ ̄)d 做点赞第一人吧
没有找到数据。

作者 收到的礼物

  • 暂时没有礼物
-
在线