1 生成一个seeder文件
你可以通过 make:seeder artisan命令来生成一个 Seeder。所有通过框架生成的 Seeder 都将被放置在 database/seeds 路径:
php artisan make:seeder StudentsTableSeeder
在 seeder 类里只有一个默认方法:run。
我们可以在这个run方法中给数据库添加任何数据(在这里我们可以使用查询构造器或者Eloquent模型工厂)
我们给run方法添加如下内容
<?php use IlluminateDatabaseSeeder; use DB; use AppModelsStudent; class StudentsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { //使用基本查询构造器 DB::table('students')->insert([ 'name' => str_random(10), ]); //可以使用orm模型 Student::insert([ 'name' => str_random(10), ]); //还可以使用模型工厂 } }
2 单独调用
运行命令,调用StudentsTableSeeder类 php artisan db:seed --class=StudentsTableSeeder
我们可以发现数据表中新插入了一条数据
这里要注意一个问题,因为我设计数据库的时候增加了created_at和updated_at字段,使用查询构造器并不能自动更新这两个字段
3 批量调用
Laravle 默认为你定义了一个 DatabaseSeeder 类。你可以在这个类中使用 call 方法来运行多个其它的 seed 类,以借此控制数据填充的顺序,并且可以实现批量调用。
我们将我们生成的StudentsTableSeeder类加入到 run方法中
<?php use IlluminateDatabaseSeeder; use IlluminateDatabaseEloquentModel; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { Model::unguard(); // $this->call(UserTableSeeder::class); //这里我们可以调用更多生成的填充数据类,便于管理 $this->call(StudentsTableSeeder::class); Model::reguard(); } }
运行命令,调用DatabaseSeeder类
php artisan db:seed
我们同样可以发现数据表中多了一条数据
补充:模型工厂
我们刚才在run方法中使用的时候查询构造器,我们还可以使用Eloquent模型工厂
学习如何定义你的工厂,一旦工厂被定义(位于database/fatories文件夹下),就能使用 factory 这个辅助函数来添加数据到数据库。
涉及到两部分:
1>创建模型工厂,并调用
2>构造数据的时候可以使用 'Faker' 类,专门生成随机数据,可查看 'https://github.com/fzaninotto/Faker'
1 模型工厂示例
先查看下应用程序的 database/factories/ModelFactory.php 文件。此文件包含一个现成的工厂定义:
$factory->define(AppUser::class, function (FakerGenerator $faker) { return [ 'name' => $faker->name, 'email' => $faker->email, 'password' => bcrypt(str_random(10)), 'remember_token' => str_random(10), ]; });
以上是对User 用户模型的定义
AppUser::class 对应的就是你的模型位置,我自己在app目录下创建了Models文件夹用于存放各种模型,所以我这里要改成 AppModelsUser::class
闭包内为工厂的定义,你可以返回模型中所有属性的默认测试值。在该闭包内会接收到 Faker PHP 函数库的实例,它可以让你很方便的生成各种随机数据以进行测试。
2 创建模型工厂
//示例 对应User模型 $factory->define(AppModelsUser::class, function (FakerGenerator $faker) { return [ 'name' => $faker->name, //使用faker生成数据 'email' => $faker->safeEmail, 'password' => bcrypt(str_random(10)), //不使用faker生成数据 'remember_token' => str_random(10), ]; }); //创建一个UserAccount模型的工厂 $factory->define(AppModelsUserAccount::class, function (FakerGenerator $faker) { return [ 'qq' => rand(10000,999999999999), 'weixin' => $faker->userName, 'weibo' => $faker->word, ]; }); //同一个UserAccount模型,不同的工厂 $factory->defineAs(AppModelsUserAccount::class,'mark', function (FakerGenerator $faker) { return [ 'qq' => rand(10000,999999999999), 'weixin' => $faker->userName, 'weibo' => $faker->word, 'mark' => 1, ]; }); //同一个UserAccount模型,不同的工厂,第二种写法 //使用raw方法获取基本属性而不用重复基本用户工厂中的所有属性,获取这些属性后,只需将你要求的额外值增补进去即可 $factory->defineAs(AppModelsUserAccount::class,'mark2', function (FakerGenerator $faker) use($factory) { // 注意向闭包函数传递变量使用use方法 $user_account = $factory->raw(AppModelsUserAccount::class); return array_merge($user_account, ['mark' => 1]); });
3 使用模型工厂
1> make()创建模型但不将其保存到数据库:
$user = factory(AppUser::class)->make();
2> 如果你想要覆盖模型的一些默认值,可以传递数组值到make方法。只有指定值被替换,其他数据保持不变:
$user = factory(AppUser::class)->make([
'name' => 'dongxuemin' // 会将生成的name替换为 'dongxuemin'
]);
3> 创建多个模型集合:
$users = factory(AppUser::class, 3)->make();
4> 创建给定类型模型:
$user = factory(AppUser::class, 'admin')->make();
5> 创建多个给定类型的集合:
$user = factory(AppUser::class, 'admin', 3)->make();
6> 保存模型至数据库
可使用 create 方法来创建模型实例(相当于创建和保存两步)
$users = factory(AppModelsUser::class)->create();
或者通过make方法得到模型实例后,使用 Eloquent 的 save 方法来将它们保存至数据库
$users = factory(AppModelsUser::class)->make();
$users->save();
7>当使用 make 或 create 方法创建多个模型时,它会返回一个 Eloquent 集合实例,让你能够使用集合所提供的便利函数,像是 each
8>当模型中(appModels文件夹下的model文件中)定义了关联关系时候,我们可以增加关联至模型
//使用基本的用户工厂创建一个用户,并使用基本的用户账号工厂 factory(AppModelsUser::class)->create()->each(function($u) { $u->account()->save(factory(AppModelsUserAccount::class)->make()); }); //使用基本的用户工厂创建2个用户,并使用基本的用户账号工厂 factory(AppModelsUser::class, 2)->create()->each(function($u) { $u->account()->save(factory(AppModelsUserAccount::class)->make()); }); //使用基本的用户工厂创建2个用户,并使用 "mark" 用户账号工厂 factory(AppModelsUser::class, 2)->create()->each(function($u) { $u->account()->save(factory(AppModelsUserAccount::class,'mark')->make()); }); //使用基本的用户工厂创建2个用户,并使用 "mark2" 用户账号工厂 factory(AppModelsUser::class, 2)->create()->each(function($u) { $u->account()->save(factory(AppModelsUserAccount::class,'mark2')->make()); });
分析:可以分为两部分理解,首先,在 factory(AppUser::class, 2)->create() 这句中写明了,我们需要构建 User 类,在数据库中创建两个用户。然后,用 collection 的 each 方法为每个被创建的用户建立关联的问题数据,并且此部分使用了我们前面定义的不同工厂