You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用Eloquent单查询批量插入后如何获取创建的模型实例?

方案1:自定义模型批量插入方法(适用于自增主键场景,性能最优)

仅需1次写入查询,无额外检索查询,前提是表主键为自增整数类型。
首先在对应模型(或通用基础模型)中新增静态方法:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class User extends Model
{
    // 原有模型逻辑...

    public static function createMany(array $data): array
    {
        // 事务包裹避免并发写入导致主键不连续
        return DB::transaction(function () use ($data) {
            // 按照create方法的逻辑预生成模型实例,自动遵守$fillable、$guarded批量赋值规则
            $instances = collect($data)->map(fn ($item) => new static($item));
            
            // 执行单查询批量插入
            static::insert($instances->map->getAttributes()->toArray());
            
            // 获取批量插入最后一条记录的自增ID
            $lastId = static::getConnection()->getPdo()->lastInsertId();
            
            // 倒推所有记录的主键ID,给实例标记已写入状态
            return $instances->sortByDesc(fn ($_, $index) => $index)
                ->map(function (Model $instance) use (&$lastId) {
                    $instance->setAttribute($instance->getKeyName(), $lastId--);
                    $instance->exists = true;
                    return $instance;
                })
                ->sortKeys()
                ->toArray();
        });
    }
}

调用方式非常简单:

$users = User::createMany([
    ['name' => 'Tom'],
    ['name' => 'Jerry'],
]);

// 直接获取带主键的完整模型实例
echo $users[0]->id; // 输出第一条插入记录的主键

注意:InnoDB引擎下,单条INSERT语句批量插入的自增ID一定是连续的,该方案主键匹配不会出现错乱。


方案2:UUID/自定义非自增主键场景

如果使用UUID、雪花ID这类非自增主键,逻辑更简单,插入前提前生成主键即可,完全不需要额外查询:

$users = collect([
    ['name' => 'Tom'],
    ['name' => 'Jerry'],
])->map(function ($item) {
    $user = new User($item);
    $user->id = str()->uuid(); // 提前生成自定义主键
    return $user;
});

// 批量插入
User::insert($users->map->getAttributes()->toArray());

// 标记实例已入库,直接使用
$users->each->setAttribute('exists', true);

方案3:小数据量临时方案

如果插入数据量极小(单次不超过10条),不想额外封装方法,可以直接遍历调用create,缺点是会产生N次写入查询,性能较低:

$users = collect([
    ['name' => 'Tom'],
    ['name' => 'Jerry'],
])->map(fn ($item) => User::create($item))->toArray();

内容的提问来源于stack exchange,提问作者Nite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 18:12:02