ThinkPHP中saveAll方法的使用和详解

@高效码农  July 27, 2023

一、saveAll方法的使用

  1. saveAll方法新增数据返回的是包含新增模型(带自增ID)的数据集对象。
  2. saveAll方法新增数据默认会自动识别数据是需要新增还是更新操作,当数据中存在主键的时候会认为是更新操作。
$user = new User;
$list = [
    ['name'=>'thinkphp','email'=>'thinkphp@qq.com'],
    ['name'=>'onethink','email'=>'onethink@qq.com']
];
$user->saveAll($list);

二、saveAll方法的详解

源码:

/**
     * 保存多个数据到当前数据对象
     * @access public
     * @param  array   $dataSet 数据
     * @param  boolean $replace 是否自动识别更新和写入
     * @return Collection
     * @throws \Exception
     */
    public function saveAll($dataSet, $replace = true)
    {
        $db = $this->db(false);
        $db->startTrans();

        try {
            $pk = $this->getPk();

            if (is_string($pk) && $replace) {
                $auto = true;
            }

            $result = [];

            foreach ($dataSet as $key => $data) {
                if ($this->exists || (!empty($auto) && isset($data[$pk]))) {
                    $result[$key] = self::update($data, [], $this->field);
                } else {
                    $result[$key] = self::create($data, $this->field, $this->replace);
                }
            }

            $db->commit();

            return $this->toCollection($result);
        } catch (\Exception $e) {
            $db->rollback();
            throw $e;
        }
    }
  1. 因为save()方法在多次调用时,第一次以后默认执行的都是更新操作;且循环调用save()方法在执行效率上有很多瑕疵;所以我们需要用到saveAll()方法
  2. 在使用saveAll()方法,批量更新时如果出现错误整个更新内容都会回滚
  3. 新增数据的最佳实践原则:使用create方法新增数据,使用saveAll批量新增数据。
  4. 批量更新仅能根据主键值进行更新,其它情况请使用 foreach 遍历更新。
  5. 测试saveAll()方法的失败,需要将ID置空或者修改不存在的ID


评论已关闭