文章大纲

对thinkphp里duplicate函数的误解

2024-05-13 16:35:22


duplicate的引入


thinkphp5.2增加了duplicate方法,从而实现了mysql的duplicate on update功能。

就是当数据在表里存在时,则更新当前数据,不存在则新增数据。



duplicate函数的正确理解


duplicate本身作为动词,就有复制的意思。

duplicate函数的参数是用来提供判断该数据是否在数据表里已经存在。

判断存在的前提条件是根据数据表的主键或组合唯一索引。

所以duplicate的功能就是:没有索引限制时就直接复制一条数据;有索引限制时,则先通过主键或唯一索引判断数据是否存在,再来决定是数据新增还是更新。



save和insert的区别


经过测试,在duplicate后用insert和save,除了返回值略有出入,插入还是更新的效果是一致的。

无第二参数时,insert和save的返回值意义是一样的:


$resVal = $modelBlock->strict(false)->duplicate($insertData)->insert($insertData);


1:插入数据

2:数据存在,有更新

0:数据存在,无更新


有第二参数时,save返回值无变化,但insert可以返回当前记录的主键ID值:


$resVal = $modelBlock->strict(false)->duplicate($insertData)->insert($insertData, true);


新ID值:插入数据

当前ID:数据存在,有更新

0:数据存在,无更新


duplicate使用注意点


1. 当duplicate参数里,既存在主键又存在组合唯一索引时,主键的优先级最高。

2. 通过上面返回值可以看出,当数据已经存在时,insert是无法通过返回值获取主键的,所以某些场合还是得通过查找的方式来判断数据是否已经存在,因为这样无论存在还是不存在,我们都可以获取到主键ID的值。


实在想用duplicate,我想出一个办法解决上面第2小点的问题:就是在insertData里加入时间更新的数据。


$insertData = ['equipment_id' => $equipmentId, 'title' => $title, 'field_name' => $title, 'status'=>1, 'update_time' => $nowTime];
例如上面代码里,再多加一项update_time的数据即可,这样就可以保证数据存在时,一定会更新了。



使用duplicate的好处


就是写代码更方便了。同样的功能,如果按照先去查找再来if else,就至少要5行代码了。


duplicate的误用


记录下来,加深印象,避免下次继续犯错。

我的代码:

就是我错误的认为,duplicate函数会根据参数里提供的字段去数据库表里检查数据是否存在,我们就不用在数据库表里去创建唯一索引进行约束了。

实践下来,已经证明上面恰恰是我对此函数功能的误解。



我要评论
评论列表