Laravel中数据迁移与数据填充的详细步骤
前⾔
这是⼀篇基础教程,对标 Laravel ⽂档中的和,分享出来供⼤家参考学习,下⾯话不多说了,来⼀起看看详细的介绍把。
关于Laravel数据库迁移的理解
最初看到laravel框架中迁移的时候,会以为这个迁移是把数据从⼀个数据库中迁到另⼀个数据库中,⼜或者是从⼀个服务器迁移到另⼀个服务器中。我⾃⼰学习有⼀个学习⽅法叫做顾名思义,所以所述是我的第⼀反应,但是学了以后发现这个迁移不是我理解中的迁移,但⼜不知道为什么叫做迁移,所以去百科查了⼀下。
迁移是指已经获得的知识、技能,甚⾄⽅法和态度对学习新知识、新技能的影响。这种影响可能是积极的,也可能是消极的,前者叫正迁移或简称迁移,后者叫负迁移或⼲扰。迁移⾸先是使习得的经验得以概括化、系统化,形成⼀种稳定的整合的⼼理结构,从⽽更好地调节⼈的⾏为,并能动地作⽤于客观世界。迁移是向能⼒转化的关键。能⼒的形成⼀⽅⾯依赖于知识、技能的掌握;另⼀⽅⾯也依赖于所掌握知识和技能的不断概括化、系统化。——引⽤于360百科
看完上⾯的百科说明,其实才明⽩什么叫做数据库迁移,总结⼀下,迁移是指某种影响,所以数据库迁移是通过对迁移⽂件的修改对数据库造成的影响,这种影响其实就是操作数据库。
换句通俗的话说,是在laravel中有⼀个⽂件,这个⽂件中写了laravel本⾝内置的对数据库的“命令“,例如可以创建修改删除库、表、字段。通过这些⽂件中的代码,便可以通过版本控制达到控制数据库的⽬的,⾄于如何通过⽂件操作数据库,我们可以看⽂档中的具体说明。
migration
Laravel 中提供了数据库迁移的⽅式来管理数据库,想象⼀个场景:在⼀个多⼈开发的项⽬中,你的同事修改了某个数据库结构并修改了代码,通过 git 你可以即时的同步同事修改的代码,但是数据库结构,你只能通过⼿⼯的⽅式来复制同事修改的SQL 语句,执⾏以保证数据库的结构⼀致。那么,Laravel 中的数据库迁移概念,就是⽤于解决团队中保证数据库结构⼀致的⽅案。
migration 使⽤⾮常简单,编写⼀定的 php 代码并执⾏,那么 Laravel 就会⾃动的更新数据库。假设你的同事要修改数据库某个字段,那么只要编写 php 代码,接着你通过 git 更新了代码,执⾏ migrate 操作之后,你的数据库结构就和他的同步了。下⾯我们就来看具体的使⽤⽅法。
migrate
Laravel 把编写数据库改动的 php 代码称为迁移,可以通过php artisan make:migration filename 的⽅式来创建迁移⽂件。假设你需要创建⼀张新的 user 表,那么你可以通过执⾏php artisan make:migration create_user_table --create=user 来创建⼀个迁移⽂件,执⾏命令会在 database/migrations/ ⽬录下建⽴⼀个⽂件创建时间_filename 的 php ⽂件,那么这个⽂件就是我们接下来⽤来编写数据库结构变化的⽂件了。这⾥要提⼀点,虽然说创建迁移⽂件的名称可以随意,但是为了管理⽅便,最好⽂件名可以体现要执⾏的数据库操作,⽐如这⾥我们要创建⼀张 user 表,所以⽂件名称为 create_user_table。
php artisan make:migration filename 有两个可选参数
--create=tablename 表明该迁移是⽤来创建表。
--table=tablename 表明该迁移是⽤来对 tablename 这张表进⾏操作。
我们创建出来的迁移⽂件 create_user_table 会包含两个⽅法。
public function up()
{
Schema::create('user', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('user');
}
这两个⽅法是互逆的操作,⽐如我们可以再 up ⽅法中编写我们要创建的 user 表的相关信息,⽽ down ⽅法中则是删除 user 表的操作。这样,我们就可以做到回滚操作,当我们创建 user 表之后发现某个字段名写错了,就可以通过 down 来删除 user 表,进⽽重新建⽴ user 表。
假设 user 表有 id,username,email 三个字段,那么可以再 up ⽅法中写
public function up()
{
Schema::create('user', function (Blueprint $table) {
$table->increments('id')->index()->comment('⽤户id');
$table->string('name')->default('')->comment('⽤户名');
$table->string('email')->nullable()->comment('⽤户邮箱');
$table->timestamps();
});
}
⼀般,我们的逻辑会在闭包函数中写。上⾯的代码,即时不能完全明⽩,也可以⼤概猜出以下⼏点:
我们操作的表是 user 表。
user 表中定义了 id 字段,因为调⽤了 increments ⽅法,所以 id 为 auto_increment,调⽤了 index ⽅法说明给 id 添加了索引,最后 comment 等同于注释。
有了 id 的经验,那么 name 字段也很好理解了,string ⽅法说明 name 是 varchar/char    类型的,default 定义了 name 字段的默认值。
email 字段调⽤了 nullable ⽅法说明运⾏ email 字段为空。
定义字段结构的时候可以使⽤链式调⽤的⽅式。
Laravel 中的⽅法是满⾜你对 sql 语句的所有操作,如果你需要定义⼀个类型为 text 的字段,那么可以调⽤ text() ⽅法,更多的⽅法说明可以参见⽂档 Laravel 数据库结构构造器。
我们已经编写好了 user 表的结构,接下来执⾏php artisan migrate,Laravel 会根据 create ⽅法⾃动为我们创建 user 表。⾄此,我们已经成功的通过 Larvel 的迁移功能来实现创建表。
Rollback
使⽤ Laravel 的迁移功能可以有后悔药吃。
执⾏php artisan migrate创建 user 表之后,觉得不⾏,不要 user 这张表,于是你打算删除这张表。那么这时候我们就要使⽤刚刚说到的 down ⽅法了。
public function down()
{
Schema::dropIfExists('user');
}
这⾥ Laarvel 已经为我们写好逻辑了,dropIfExists 函数就是⽤来删除表,我们只需要执⾏php artisan migrate :rollback 就可以回滚到执⾏php artisan migrate之前的状态。
重命名表
除了创建表,也可以⽤迁移记录表的其他任何操作,包括修改表属性,修改字段等等操作。这⾥再举个例⼦说明如何⽤迁移来对表进⾏重命名。
1、假设有表 user,我们需要对它重命名为 users。⾸先要执⾏php artisan make:migration rename_user_to_users --table user来创建迁移⽂件。
2、在 up ⽅法中写我们要重命名表的逻辑。
public function up()
{
Schema::table('user', function (Blueprint $table) {
Schema::rename('user','users');
});
}
3、为了可以 rollback 可以顺利执⾏,我们还需要在 down ⽅法中编写撤销重命名操作的逻辑。
public function up()
{
Schema::table('user', function (Blueprint $table) {
/
/
Schema::rename('users','user');
});
}
4、最后执⾏php artisan migrate 就就可以完成对 user 表的重命名操作。如果需要回滚,只要执⾏ php artisan migrate:rollback。
你会发现,如果执⾏⼀次迁移之后,如果执⾏第⼆次迁移是不会重复执⾏的,这是因为 Laravel 会在数据库中建⽴⼀张migrations 的表来记录哪些已经进⾏过迁移。
基本的 migration 介绍就到这⾥,以上的内容可以应对⼤部分的需求,如果需要更详细的介绍,可能需要阅读 Laravel 那不知所云的⽂档了。:)
Seeder
Laravel 中除了 migration 之外,还有⼀个 seeder 的东西,这个东西⽤于做数据填充。假设项⽬开发中
需要有⼀些测试数据,那么同样可以通过编写 php 代码来填充测试数据,那么通过 git 同步代码,所有的⼈都可以拥有⼀份同样的测试数据。
同样,数据填充在 Laravel 中被称为 Seeder,如果需要对某张表填充数据,需要先建⽴⼀个 seeder。通过执⾏ php artisan make:seeder UserTableSeeder 来⽣成⼀个 seeder 类。这⾥我们希望填充数据的表⽰ test 表,所以名字为UserTableSeeder。当然这个名字不是强制性的,只是为了做到见名知意。
创建 UserTableSeeder 之后会在 database/seeders ⽬录下⽣成⼀个 UserTableSeeder 类,这个类只有⼀个 run ⽅法。你可以在 run ⽅法中写插⼊数据库的代码。假设我们使⽤ DB facade 来向 test 表插⼊数据。
class UserTableSeeder extends Seeder
{
drop table if exists user
public function run()
{
DB::table('users')->insert($insertData);
}
}
编写完代码之后,执⾏php artsian db:seeder --class= UserTableSeeder 来进⾏数据填充。执⾏完毕之后查看数据库已经有数据了。
如果我们有多个表要进⾏数据填充,那么不可能在编写完 php 代码之后,逐个的执⾏php artisan db:seeder --class=xxxx 来进⾏填充。有⼀个简便的⽅法。在 DatabaseSeeder 的 run ⽅法中添加⼀⾏$this->call(UserTableSeeder::class);,然后执⾏php artisan db:seeder,那么 Laravel 就会执⾏ DatabaseSeeder 中的 run ⽅法,然后逐个执⾏迁移。
和 migration 不同,如果多次执⾏php artisan db:seeder 就会进⾏多次数据填充。
加⼊你想⼀次性插⼊⼤量的测试数据,那么在 run ⽅法中使⽤ DB facade 来逐个插⼊显然不是⼀个好的⽅法。Laravel 中提供了⼀种模型⼯⼚的⽅式来创建创建⼤量的数据。
模型⼯⼚
模型⼯⼚,意味着本质其实是⼀个⼯⼚模式。那么,在使⽤模型⼯⼚创建数据需要做两件事情
创建⼯⼚,定义好⼯⼚要返回的数据。
调⽤⼯⼚获取数据。
Laravel 中通过执⾏php artisan make:factory UserFactory --model=User 来为 User Model 创建⼀个⼯⼚类,该⽂件会放在database/factory ⽬录下。打开该⽂件可以看到如下代码:
$factory->define(App\User::class, function (Faker $faker) {
return [
//
];
});
这⾥, return 的值就是我们第 2 步调⽤⼯⼚获取到的数据。⽣成数据的逻辑也只需要写在闭包函数中就可以。这⾥需要提⼀下 Faker 这个类。这是⼀个第三⽅库,Laravel 集成了这个。这个库的作⽤很好玩:**⽤于⽣成假数据。**假设 User 表需要插⼊ 100 个⽤户,那么就需要 100 个 username,那么你就
不必⾃⼰写逻辑⽣成⼤量的 test01,test02 这样⼦幼稚的假数据,直接使⽤ Faker 类,会替你⽣成⼤量逼真的 username。(我也不知道这个算不算⽆聊了 :)。。。)。
现在假设 User 表有 id, email, username 三个字段,那么我要⽣成 100 个⽤户,⾸先在⼯⼚类中实现逻辑。
$factory->define(App\Models\User::class, function (Faker $faker) {
return [
// 直接调⽤ faker API ⽣成假数据,更多 faker 相关查看⽂档。
'username' => $faker->name,
'email' => $faker->unique()->safeEmail,
];
});
现在,我们已经定义好了⼯⼚,现在我们就要在 UserSeeder@run 函数中使⽤模型⼯⼚来⽣成测试数据。
class UserTableSeeder extends Seeder
{
public function run()
{
factory(App\User::class)->times(10)->make()->each(function($user,$index){
$user->save();
});
}
}
run 函数中这⼀波⾏云流⽔的链式调⽤在我刚刚开始接触 Laravel 的时候也是⼀脸⿊线,不过习惯之后感觉这代码可读性确实很强
factory(App\User::class)指明返回哪个⼯⼚,参数 App\User::class 就是⼯⼚的唯⼀标识。这⾥我们在定义⼯⼚的时候define 的第⼀个参数已经指明了。
->times(10) 指明需要⼯⼚模式⽣成 10 个 User 数据。即会调⽤ 10 次 define 函数的第⼆个参数。
->make() 把⽣成的 10 个 User 数据封装成 Laravel 中的集合对象。
->each() 是 Laravel 集合中的函数,each 函数会针对集合中的每个元素进⾏操作。这⾥直接把数据保存到数据库。
好了,数据迁移和数据填充的基本操作也就这些了。更多复杂的⽤法。。。。也不⼀定能⽤上。
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,如果有疑问⼤家可以留⾔交流,谢谢⼤家对的⽀持。