ThinkPHP6 在批量插入saveAll() 的是循环调用save()方法, 如果需要提交大量数据, 还是自己拼sql 比较快.
源码位置 topthink/think-orm/src/Model.php
757行
/**
* 保存多个数据到当前数据对象
* @access public
* @param iterable $dataSet 数据
* @param boolean $replace 是否自动识别更新和写入
* @return Collection
* @throws \Exception
*/
public function saveAll(iterable $dataSet, bool $replace = true): Collection
{
$db = $this->db();
$result = $db->transaction(function () use ($replace, $dataSet) {
$pk = $this->getPk();
if (is_string($pk) && $replace) {
$auto = true;
}
$result = [];
$suffix = $this->getSuffix();
foreach ($dataSet as $key => $data) {
if ($this->exists || (!empty($auto) && isset($data[$pk]))) {
$result[$key] = static::update($data, [], [], $suffix);
} else {
$result[$key] = static::create($data, $this->field, $this->replace, $suffix);
}
}
return $result;
});
return $this->toCollection($result);
}
可以看到, saveAll 循环数据集后根据数据情况分别调用 create() 和 update 方法, 这么做的好处是可以一起完成更新和新增.
所以当批量数据写入(一般是导入处理)时建议手动拼写sql
public static function createMultiple(array $data)
{
$sql = "INSERT INTO `data`(`id`,`num`,`title`,`content`) VALUES ";
foreach ($data as $value) {
$sql .= "('" . $value['id'] . "','" . $value['num'] . "','" . $value['title'] . "','" . $value['content'] . "'),";
}
$sql = rtrim($sql, ',');
Db::execute($sql);
}
另: mysql 批量写入有大小限制, 注意分开批量, 可以使用 array_chunk 处理数组, 或嵌套循环多次批量插入
很赞哦! ( 1 )