Seeder 与 Factory 配合使用:Seeder 是执行插入的脚本容器,Factory 负责构造数据;Laravel 8+ 工厂为类形式,需手动指定模型,调用 create() 入库,注意命名空间加载、unique() 作用域及性能优化。
Seeder 本身不生成数据,它只是执行数据插入的“脚本容器”;真正负责构造测试数据的是 Factory。Laravel 8+ 默认已将 Factory 迁移到类形式(UserFactory),不再用闭包定义,这点容易导致旧教程跑不通。
php artisan make:factory UserFactory 会生成一个继承 Factory 的类,需手动指定模型:protected $model = User::class;
UserFactory::new()->count(50)->create() 才算真正批量插入——注意是 create(),不是 make()(后者只实例化不入库)for() 关联(如 for(User::factory())),必须确保关联模型已存在或同时被创建,否则外键约束报错这是最常踩的坑:Laravel 不会自动加载 databa 下的类,尤其在非默认命名空间下。Laravel 9+ 默认工厂类在
se/factoriesDatabase\Factories 命名空间,但 composer.json 的 autoload 配置可能没覆盖到。
composer.json 中 "psr-4" 是否包含:"Database\\Factories\\": "database/factories/"
composer dump-autoload,否则 PHP 找不到类database/factories/User/ProfileFactory.php),命名空间要严格匹配路径:Database\Factories\User\ProfileFactory
faker 的 unique() 是懒加载机制,只对当前调用链生效。如果在循环中多次调用 UserFactory::new()->create(),每次都是独立上下文,unique() 不跨调用记忆。
public function definition()
{
return [
'email' => $this->faker->unique()->safeEmail,
'name' => $this->faker->name,
];
}
count() 一次性创建多条:UserFactory::new()->count(100)->create(),此时 unique() 有效$this->faker->unique()->numerify('user###@test.com') 加随机后缀email 字段加 unique() 约束,能提前暴露重复问题,比靠 Factory 更可靠默认每条 create() 都走完整 Eloquent 生命周期(事件、强制转换、验证钩子等),对纯填充场景是冗余开销。
DB::table('users')->insert($data) 批量插入原始数组,速度提升 5–10 倍(但绕过模型逻辑,不能触发 creating 等事件)state() 预设高频字段,减少闭包执行次数:UserFactory::new()->state(['status' => 'active'])->count(1000)->create()
php artisan db:seed --force,避免误操作;本地开发可加 if (app()->environment('local')) { ... } 包裹敏感 Seederdefinition() + count()->create() 就够用。过度设计工厂逻辑反而让 Seeder 难以调试,尤其当多个 Factory 互相依赖时,顺序和事务边界很容易出错。