Laravel5中批量插入artists、albums、songs多层关联数据的问题
解决Laravel 5中批量插入多层关联歌曲数据的问题
嘿,我之前也处理过类似的多层关联批量插入需求,既然你已经搞定了艺术家(artists)和专辑(albums)的批量插入,那给你分享两种靠谱的方式来搞定歌曲(songs)和对应专辑的关联插入,保证关联关系不出错:
方法一:利用模型关联的createMany方法(推荐,自动维护关联)
这种方式会自动帮你设置songs表的album_id外键,还能触发模型的生命周期事件,适合需要模型逻辑的场景。
步骤说明:
先确保你的模型关联定义是正确的(这个很重要,不然关联会失效):
- Artist模型:
public function albums() { return $this->hasMany(Album::class); } - Album模型:
public function artist() { return $this->belongsTo(Artist::class); } public function songs() { return $this->hasMany(Song::class); } - Song模型:
public function album() { return $this->belongsTo(Album::class); }
- Artist模型:
遍历已插入的艺术家和专辑,批量创建歌曲:
假设你已经有了插入后的$artists集合(如果是之前插入的,可以用Artist::with('albums')->get()加载关联),然后用事务包裹保证数据一致性:use Illuminate\Support\Facades\DB; DB::transaction(function () use ($artists) { $artists->each(function ($artist) { // 遍历该艺术家的所有专辑 $artist->albums->each(function ($album) { // 构造当前专辑对应的歌曲数据,根据你的需求调整字段 $songsData = [ ['title' => '《晴天》', 'duration' => '4:29', 'lyricist' => '周杰伦'], ['title' => '《七里香》', 'duration' => '4:57', 'lyricist' => '方文山'], // 更多歌曲数据... ]; // 批量插入歌曲,自动设置album_id $album->songs()->createMany($songsData); }); }); });
方法二:直接用insert批量插入(高效,适合大数据量)
如果你的歌曲数据量很大,追求插入效率,可以直接用insert方法一次性插入,但需要手动指定album_id,而且不会触发模型事件,也不会自动填充created_at/updated_at(如果需要的话得手动加)。
示例代码:
// 构造包含album_id的歌曲数据数组,确保每个歌曲对应正确的专辑ID $songsData = [ ['album_id' => 1, 'title' => '《晴天》', 'duration' => '4:29', 'lyricist' => '周杰伦', 'created_at' => now(), 'updated_at' => now()], ['album_id' => 1, 'title' => '《七里香》', 'duration' => '4:57', 'lyricist' => '方文山', 'created_at' => now(), 'updated_at' => now()], ['album_id' => 2, 'title' => '《告白气球》', 'duration' => '3:35', 'lyricist' => '方文山', 'created_at' => now(), 'updated_at' => now()], // 更多歌曲数据... ]; // 开启事务,一次性插入所有歌曲 DB::transaction(function () use ($songsData) { Song::insert($songsData); });
注意点:
- 用
insert时,必须手动指定所有必填字段,包括外键album_id和时间戳(如果你的表开启了自动时间戳,insert不会自动填充,所以要手动加now()) - 这种方式不会触发模型的
creating/created等事件,如果你的模型有这些逻辑,建议还是用方法一
额外提醒
不管用哪种方法,都一定要用DB::transaction包裹操作,这样如果中间插入出错,所有操作都会回滚,避免出现数据不一致的情况(比如艺术家和专辑插入了,但歌曲没插成功的尴尬场景)。
内容的提问来源于stack exchange,提问作者Wu Yu
相关产品推荐
相关产品推荐

