本文目录导读:

在Laravel中,数据填充是开发过程中非常重要的一环,我来详细讲解如何编写数据填充器。
基础数据填充器
创建填充器
# 创建基本填充器 php artisan make:seeder UserSeeder # 创建带模型的填充器 php artisan make:seeder ProductSeeder --model=Product # 创建所有表的填充器(生产环境常用) php artisan make:seeder DatabaseSeeder
基础填充器示例
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class UserSeeder extends Seeder
{
public function run(): void
{
// 单条插入
User::create([
'name' => 'Admin',
'email' => 'admin@example.com',
'password' => bcrypt('password'),
]);
// 多条插入
$users = [
['name' => 'User1', 'email' => 'user1@example.com', 'password' => bcrypt('secret')],
['name' => 'User2', 'email' => 'user2@example.com', 'password' => bcrypt('secret')],
];
foreach ($users as $user) {
User::create($user);
}
}
}
使用工厂(Factory)
创建工厂
php artisan make:factory UserFactory --model=User
工厂定义
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => bcrypt('password'),
'remember_token' => Str::random(10),
];
}
// 自定义状态
public function admin(): static
{
return $this->state(fn (array $attributes) => [
'is_admin' => true,
]);
}
}
在填充器中使用工厂
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
public function run(): void
{
// 创建10个用户
User::factory()->count(10)->create();
// 创建特殊用户
User::factory()->admin()->create();
// 批量创建并指定字段
User::factory()->count(5)->create([
'role' => 'editor'
]);
}
}
处理关联数据
<?php
namespace Database\Seeders;
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run(): void
{
// 创建用户及其关联文章
User::factory()
->has(
Post::factory()
->count(3)
->has(Comment::factory()->count(5))
)
->create();
// 使用关联方法
User::all()->each(function ($user) {
Post::factory()
->count(2)
->for($user)
->create()
->each(function ($post) {
Comment::factory()->count(3)->create([
'post_id' => $post->id,
'user_id' => User::inRandomOrder()->first()->id,
]);
});
});
}
}
复杂数据填充
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Product;
use App\Models\Category;
class ProductSeeder extends Seeder
{
public function run(): void
{
// 使用循环和随机数据
for ($i = 0; $i < 50; $i++) {
Product::create([
'name' => "Product {$i}",
'sku' => 'SKU-' . str_pad($i, 4, '0', STR_PAD_LEFT),
'price' => rand(10, 1000) / 10,
'stock' => rand(0, 100),
'category_id' => Category::inRandomOrder()->first()->id,
'is_active' => rand(0, 1) === 1,
'description' => "Description for product {$i}",
'specifications' => json_encode([
'weight' => rand(1, 10) . 'kg',
'color' => ['红', '蓝', '绿'][rand(0, 2)],
'material' => '塑料'
]),
]);
}
// 批量插入(大数据量时效率更高)
$products = [];
for ($i = 100; $i < 200; $i++) {
$products[] = [
'name' => "Bulk Product {$i}",
'price' => rand(10, 500),
'created_at' => now(),
'updated_at' => now(),
];
}
DB::table('products')->insert($products);
}
}
数据填充策略
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
// 分步执行
$this->call([
UserSeeder::class,
CategorySeeder::class,
ProductSeeder::class,
OrderSeeder::class,
]);
// 或条件执行
if (app()->environment('production')) {
$this->call(ProductionSeeders::class);
} else {
$this->call(DevelopmentSeeders::class);
}
}
}
高级技巧
数据集修改器
<?php
namespace Database\Factories;
class ProductFactory extends Factory
{
public function definition(): array
{
return [
'name' => $this->faker->word,
'price' => $this->faker->randomFloat(2, 10, 1000),
'image' => $this->faker->imageUrl(),
];
}
// 特定状态
public function expensive(): static
{
return $this->state(function (array $attributes) {
return ['price' => fake()->randomFloat(2, 5000, 10000)];
});
}
}
使用模型事件
// 在填充器中使用模型事件
Model::creating(function ($model) {
$model->uuid = Str::uuid();
});
执行数据填充
# 运行所有填充器
php artisan db:seed
# 运行特定填充器
php artisan db:seed --class=UserSeeder
# 初始化后填充
php artisan migrate:fresh --seed
# 指定环境
php artisan db:seed --env=testing
# 在代码中执行
DB::table('users')->truncate(); // 清空表
Artisan::call('db:seed', ['--class' => 'UserSeeder', '--force' => true]);
注意事项
避免重复数据
<?php
namespace Database\Seeders;
class UserSeeder extends Seeder
{
public function run(): void
{
// 使用 firstOrCreate 或 updateOrCreate
User::firstOrCreate(
['email' => 'admin@example.com'],
['name' => 'Admin', 'password' => bcrypt('password')]
);
}
}
性能优化
// 大数据量时使用 chunk
Product::chunk(100, function ($products) {
foreach ($products as $product) {
// 处理数据
}
});
// 使用 DB::table 直接插入
DB::table('products')->insert($data);
生产环境安全
// 在填充器中检查环境
if (app()->isProduction() && !$this->command->confirm('是否在正式环境运行?')) {
$this->command->error('已取消');
return;
}
这些是Laravel数据填充的主要方法和最佳实践,根据项目需求选择合适的策略,可以高效地完成数据初始化工作。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播