Laravel中数据迁移与数据填充的详细步骤
前言
这是一篇基础教程,对标Laravel文档中的数据迁移和数据填充,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍把。
关于Laravel数据库迁移的理解
最初看到laravel框架中迁移的时候,会以为这个迁移是把数据从一个数据库中迁到另一个数据库中,又或者是从一个服务器迁移到另一个服务器中。我自己学习有一个学习方法叫做顾名思义,所以所述是我的第一反应,但是学了以后发现这个迁移不是我理解中的迁移,但又不知道为什么叫做迁移,所以去百科查了一下。
迁移是指已经获得的知识、技能,甚至方法和态度对学习新知识、新技能的影响。这种影响可能是积极的,也可能是消极的,前者叫正迁移或简称迁移,后者叫负迁移或干扰。迁移首先是使习得的经验得以概括化、系统化,形成一种稳定的整合的心理结构,从而更好地调节人的行为,并能动地作用于客观世界。迁移是向能力转化的关键。能力的形成一方面依赖于知识、技能的掌握;另一方面也依赖于所掌握知识和技能的不断概括化、系统化。——引用于360百科
看完上面的百科说明,其实才明白什么叫做数据库迁移,总结一下,迁移是指某种影响,所以数据库迁移是通过对迁移文件的修改对数据库造成的影响,这种影响其实就是操作数据库。
换句通俗的话说,是在laravel中有一个文件,这个文件中写了laravel本身内置的对数据库的“命令“,例如可以创建修改删除库、表、字段。通过这些文件中的代码,便可以通过版本控制达到控制数据库的目的,至于如何通过文件操作数据库,我们可以看文档中的具体说明。
migration
Laravel中提供了数据库迁移的方式来管理数据库,想象一个场景:在一个多人开发的项目中,你的同事修改了某个数据库结构并修改了代码,通过git你可以即时的同步同事修改的代码,但是数据库结构,你只能通过手工的方式来复制同事修改的SQL语句,执行以保证数据库的结构一致。那么,Laravel中的数据库迁移概念,就是用于解决团队中保证数据库结构一致的方案。
migration使用非常简单,编写一定的php代码并执行,那么Laravel就会自动的更新数据库。假设你的同事要修改数据库某个字段,那么只要编写php代码,接着你通过git更新了代码,执行migrate操作之后,你的数据库结构就和他的同步了。下面我们就来看具体的使用方法。
migrate
Laravel把编写数据库改动的php代码称为迁移,可以通过phpartisanmake:migrationfilename的方式来创建迁移文件。假设你需要创建一张新的user表,那么你可以通过执行phpartisanmake:migrationcreate_user_table--create=user来创建一个迁移文件,执行命令会在database/migrations/目录下建立一个文件创建时间_filename的php文件,那么这个文件就是我们接下来用来编写数据库结构变化的文件了。这里要提一点,虽然说创建迁移文件的名称可以随意,但是为了管理方便,最好文件名可以体现要执行的数据库操作,比如这里我们要创建一张user表,所以文件名称为create_user_table。
phpartisanmake:migrationfilename有两个可选参数
- --create=tablename表明该迁移是用来创建表。
- --table=tablename表明该迁移是用来对tablename这张表进行操作。
我们创建出来的迁移文件create_user_table会包含两个方法。
publicfunctionup() { Schema::create('user',function(Blueprint$table){ $table->increments('id'); $table->timestamps(); }); } publicfunctiondown() { Schema::dropIfExists('user'); }
这两个方法是互逆的操作,比如我们可以再up方法中编写我们要创建的user表的相关信息,而down方法中则是删除user表的操作。这样,我们就可以做到回滚操作,当我们创建user表之后发现某个字段名写错了,就可以通过down来删除user表,进而重新建立user表。
假设user表有id,username,email三个字段,那么可以再up方法中写
publicfunctionup() { 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表的结构,接下来执行phpartisanmigrate,Laravel会根据create方法自动为我们创建user表。至此,我们已经成功的通过Larvel的迁移功能来实现创建表。
Rollback
使用Laravel的迁移功能可以有后悔药吃。
执行phpartisanmigrate创建user表之后,觉得不行,不要user这张表,于是你打算删除这张表。那么这时候我们就要使用刚刚说到的down方法了。
publicfunctiondown() { Schema::dropIfExists('user'); }
这里Laarvel已经为我们写好逻辑了,dropIfExists函数就是用来删除表,我们只需要执行phpartisanmigrate:rollback就可以回滚到执行phpartisanmigrate之前的状态。
重命名表
除了创建表,也可以用迁移记录表的其他任何操作,包括修改表属性,修改字段等等操作。这里再举个例子说明如何用迁移来对表进行重命名。
1、假设有表user,我们需要对它重命名为users。首先要执行phpartisanmake:migrationrename_user_to_users--tableuser来创建迁移文件。
2、在up方法中写我们要重命名表的逻辑。
publicfunctionup() { Schema::table('user',function(Blueprint$table){ Schema::rename('user','users'); }); }
3、为了可以rollback可以顺利执行,我们还需要在down方法中编写撤销重命名操作的逻辑。
publicfunctionup() { Schema::table('user',function(Blueprint$table){ // Schema::rename('users','user'); }); }
4、最后执行phpartisanmigrate就就可以完成对user表的重命名操作。如果需要回滚,只要执行phpartisanmigrate:rollback。
你会发现,如果执行一次迁移之后,如果执行第二次迁移是不会重复执行的,这是因为Laravel会在数据库中建立一张migrations的表来记录哪些已经进行过迁移。
基本的migration介绍就到这里,以上的内容可以应对大部分的需求,如果需要更详细的介绍,可能需要阅读Laravel那不知所云的文档了。:)
Seeder
Laravel中除了migration之外,还有一个seeder的东西,这个东西用于做数据填充。假设项目开发中需要有一些测试数据,那么同样可以通过编写php代码来填充测试数据,那么通过git同步代码,所有的人都可以拥有一份同样的测试数据。
同样,数据填充在Laravel中被称为Seeder,如果需要对某张表填充数据,需要先建立一个seeder。通过执行phpartisanmake:seederUserTableSeeder来生成一个seeder类。这里我们希望填充数据的表示test表,所以名字为UserTableSeeder。当然这个名字不是强制性的,只是为了做到见名知意。
创建UserTableSeeder之后会在database/seeders目录下生成一个UserTableSeeder类,这个类只有一个run方法。你可以在run方法中写插入数据库的代码。假设我们使用DBfacade来向test表插入数据。
classUserTableSeederextendsSeeder { publicfunctionrun() { DB::table('users')->insert($insertData); } }
编写完代码之后,执行phpartsiandb:seeder--class=UserTableSeeder来进行数据填充。执行完毕之后查看数据库已经有数据了。
如果我们有多个表要进行数据填充,那么不可能在编写完php代码之后,逐个的执行phpartisandb:seeder--class=xxxx来进行填充。有一个简便的方法。在DatabaseSeeder的run方法中添加一行$this->call(UserTableSeeder::class);,然后执行phpartisandb:seeder,那么Laravel就会执行DatabaseSeeder中的run方法,然后逐个执行迁移。
和migration不同,如果多次执行phpartisandb:seeder就会进行多次数据填充。
加入你想一次性插入大量的测试数据,那么在run方法中使用DBfacade来逐个插入显然不是一个好的方法。Laravel中提供了一种模型工厂的方式来创建创建大量的数据。
模型工厂
模型工厂,意味着本质其实是一个工厂模式。那么,在使用模型工厂创建数据需要做两件事情
- 创建工厂,定义好工厂要返回的数据。
- 调用工厂获取数据。
Laravel中通过执行phpartisanmake:factoryUserFactory--model=User来为UserModel创建一个工厂类,该文件会放在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[ //直接调用fakerAPI生成假数据,更多faker相关查看文档。 'username'=>$faker->name, 'email'=>$faker->unique()->safeEmail, ]; });
现在,我们已经定义好了工厂,现在我们就要在UserSeeder@run函数中使用模型工厂来生成测试数据。
classUserTableSeederextendsSeeder { publicfunctionrun() { 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函数会针对集合中的每个元素进行操作。这里直接把数据保存到数据库。
好了,数据迁移和数据填充的基本操作也就这些了。更多复杂的用法。。。。也不一定能用上。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。