tp6自带了duplicate方法了,但一些老项目用的是tp5和5.1是不支持duplicate的,这时候如果需要用到duplicate 就需要我们自己去实现了
<?php
namespace app\index\model;
use think\Model;
class BaseModel extends Model
{
// 数据插入 duplicate
public function insertAllDuplicate($data, $duplicate = null, $limit = null) {
if (!empty($duplicate)) {
if (is_array($duplicate)) {
$temp = [];
foreach ($duplicate as $key => $item) {
if (is_integer($key)) {
$temp[] = "{
$item} = VALUES({
$item})";
}
else {
$temp[] = "{
$key} = {
$item}";
}
}
$duplicate = implode(',', $temp);
}
}
if (!empty($limit)) {
// 分批写入 自动启动事务支持
$this->startTrans();
try {
// array_chunk 函数把数组分割为新的数组块。
//其中每个数组的单元数目由 size 参数决定。最后一个数组的单元数目可能会少几个。
//可选参数 preserve_key 是一个布尔值,它指定新数组的元素是否有和原数组相同的键(用于关联数组),还是从 0 开始的新数字键(用于索引数组)。默认是分配新的键。
$array = array_chunk($data, $limit, true);
$count = 0;
foreach ($array as $item) {
$sql = $this->fetchSql(true)->insertAll($item);
$sql = preg_replace("/INSERT\s*INTO\s*/", "INSERT IGNORE INTO ", $sql);
if (is_string($duplicate)) {
$sql = $sql . ' ON DUPLICATE KEY UPDATE '. $duplicate;
}
$count += $this->execute($sql); // 获取影响函数
}
// 提交事务
$this->commit();
} catch (\Exception $e) {
$this->rollback();
throw $e;
}
return $count;
}
else {
$sql = $this->fetchSql(true)->insertAll($data);
$sql = preg_replace("/INSERT\s*INTO\s*/", "INSERT IGNORE INTO ", $sql);
if (is_string($duplicate)) {
$sql = $sql . ' ON DUPLICATE KEY UPDATE '. $duplicate;
}
return $this->execute($sql);
}
}
}
用法
// 定义产品模型
<?php
namespace app\index\model;
use think\Model;
class Product extends BaseModel
{
}
?>
// 业务代码调用
$ProductModel = new app\index\model\Product();
$dateTime = '2023-06-15 18:00:00';
$ProductModel->insertAllDuplicate([
['title' => 'title00000000', 'img' => 'http://img.com/0000.jpg', 'update_time' => dateTime ],
['title' => 'title11111111', 'img' => 'http://img.com/11111111.jpg', 'update_time' => dateTime ],
['title' => 'title22222222', 'img' => 'http://img.com/22222222.jpg', 'update_time' => dateTime ],
['title' => 'title33333333', 'img' => 'http://img.com/33333333.jpg', 'update_time' => dateTime ],
], [
'title', // title = VALUES(title)
'update_time' => '{$dateTime}' // update_time = '{$dateTime}'
], 2);
//sql=> INSERT IGNORE INTO `product`(`title`, `img`, `update_time`) VALUES('title00000000', 'http://img.com/0000.jpg', '2023-06-15 18:00:00'), ('title11111111', 'http://img.com/11111111.jpg', '2023-06-15 18:00:00') ON DUPLICATE KEY UPDATE title = VALUES(title), update_time = '2023-06-15 18:00:00';