orm 系列 之 Eloquent使用1
Eloquent ORM
本文会是一个Eloquent的使用教程,在此之前,我们先讲述下怎么搭建环境,完整的系列请查看orm
基础环境的搭建
记录下怎么用docker搭建laravel的环境
- 新建项目
composer create-project --prefer-dist laravel/laravel eloquent
- 添加laradock
cd eloquent;git init;git submodule add https://github.com/LaraDock/laradock.git
- 创建docker
docker-compose up -d mysql nginx redis
- 进入container,修改.env,DB_HOST=mysql
docker-compose exec workspace bash
- 通过浏览器访问localhost
上面步骤完成后,我们可以通过mac上的Sequel Pro连接数据库,我们通过查看docker-compose.yml,可以知道数据库的的相关信息。
于是就可以通过设置Sequel Pro进行连接了,如下图所示
下一步是phpstorm的设置,可以参考文章如何使用PhpStorm實現TDD、重構與偵錯?
然后再是让如何在PhpStorm活用PHPDoc?,让phpstorm能自动提示laravel中的类。
通过Eloquent的Scheme Builder构建数据库
通过使用Schema Builder我们可以在设计数据库的时候,不写一行sql,通过Schema Builder,我们可以
creating, dropping, and updating a table; adding, removing, and renaming columns simple indexes,unique indexes and foreign keys
通过将Schema Builder和migration系统结合,我们可以对数据库进行版本控制!这是多么激动的一件事,一旦我们可以对数据库进行版本的控制,我们就能很轻易的将数据库状态设置到我们预期的状态,下面会分两部分进行介绍
- Schema Builder
- migrations
先介绍第一个功能Schema Builder
Schema Builder
Schema Builder让我们可以不写一行sql语句,就能完成数据库的设计,下面让我们通过几个例子来看Schema Builder的使用,从最简单的表创建开始
Route::get('create_user_table',function(){
Schema::create('users',function( Blueprint $table){
$table->increments('id');
});
});
此处create方法接受两个参数,一个是表名,第二个参数是以个闭包,里面我们指定了表的所有字段,我们可以看下create方法
// class Schema/Builder
public function create($table, Closure $callback)
{
$blueprint = $this->createBlueprint($table);
$blueprint->create();
$callback($blueprint);
$this->build($blueprint);
}
protected function build(Blueprint $blueprint)
{
$blueprint->build($this->connection, $this->grammar);
}
此处新建完blueprint后,我们就调用了传入的闭包,在闭包中设置了表的字段,最后通过build真正执行数据库操作,最后调用到了blueprint
的build方法,传入的connection是数据库连接抽象,负责数据库执行操作,grammar负责sql的拼装,而blueprint本身则存储着grammar拼装sql需要的数据,接着看blueprint的build方法
// class Schema/Blueprint
public function build(Connection $connection, Grammar $grammar)
{
foreach ($this->toSql($connection, $grammar) as $statement) {
$connection->statement($statement);
}
}
public function toSql(Connection $connection, Grammar $grammar)
{
$this->addImpliedCommands();
$statements = [];
// 此处每个command都有一个相关的grammar的compileCommand函数
foreach ($this->commands as $command) {
$method = 'compile'.ucfirst($command->name);
if (method_exists($grammar, $method)) {
if (! is_null($sql = $grammar->$method($this, $command, $connection))) {
$statements = array_merge($statements, (array) $sql);
}
}
}
return $statements;
}
此处关键是toSql函数,最后调用到了grammar的方法,此处是compileCreate方法,其代码就是sql拼装,感兴趣的可以去看代码的。
下面列举Schema支持的几个常用命令
// 重命名
Schema::rename($previousName, $newName);
// 删除表
Schema::drop($tableName);
Schema::dropIfExists($tableName);
介绍完命令后,我们来看下表的列操作,还是看代码
Route::get('create_books_table',function(){
Schema::create('books',function( Blueprint $table){
$table->increments('id');
$table->string('title',30);
$table->integer('pages_count');
$table->decimal('price',5,2);
$table->text('description');
$table->timestamps();
});
});
这些column方法,最终调用的都是下面的代码
// class Schema/Blueprint
public function addColumn($type, $name, array $parameters = [])
{
$attributes = array_merge(compact('type', 'name'), $parameters);
$this->columns[] = $column = new Fluent($attributes);
return $column;
}
因此Blueprint
有两个重要的数据$columns
和$commands
,Grammar在使用的拼装sql的时候,取得数据就是这两个地方来的。
下面将数据库的migration功能。
migrations
migration是为了解决什么问题而引入的?
我们在多人开发的过程中,每个人开发阶段不同、DB状态也不同,整合时无法知道差异,但是如果直接修改DB的话,没有记录也没办法恢复,这时候,我们就需要引入Migration了。
那什么是migration呢?
app/database/migrations/{migration}.php文件是所有对DB操作的动作,里面都是通过代码来完成DB操作的。
操作分为up/down,每个人拿到后进行版本更新,通过执行migrate操作,就可以将DB同步到相同的状态,如果有问题,我们也可以通过rollback回到之前的状态。
我们来看下一个实际的使用例子
第一步:建立migrate文件
php artisan make:migration publishers_update
第二步:编写文件
public function up()
{
Schema::create( 'publishers', function ( Blueprint $table ) {
$table->increments( 'id' );
$table->string( 'name' );
$table->timestamps();
} );
Schema::table( 'books', function ( Blueprint $table ) {
$table->integer( 'publisher_id' )->unsigned();
$table->foreign( 'publisher_id' )->references( 'id' )->on( 'publishers' );
} );
}
public function down()
{
Schema::table( 'books', function ( Blueprint $table ) {
$table->dropForeign( 'books_publisher_id_foreign' );
$table->dropColumn( 'publisher_id' );
} );
Schema::drop( 'publishers' );
}
第三步:执行migrate操作
php artisan migrate
第四步:rollback migrate操作
php artisan migrate:rollback
此处执行完后,数据库中会有新的一张表migrations
此处表中batch的作用是,我们每次执行migrate操作,如果有新的migrate操作,就会有新的batch产生,然后我们每次执行rollback,会将最大的batch进行回滚。
总结
本文主要是介绍了使用docker来构建laravel的开发环境,同时,我们也介绍了怎么说会用phpstorm来开发laravel,搭建好环境后,主要介绍了Eloquent的Schema Builder和migrations功能,通过使用Schema Builder,使得我们可以不用写一句sql就可以完成数据库设计,而migrations则使得我们在团队协作中,更好的对数据库进行版本的控制。
- SpringBoot就是这么简单
- SpringData JPA就是这么简单
- Openflow细节理解之—Buffer_id篇
- 移动商城项目总结
- 移动商城第一篇【搭建项目环境+数据模型】
- 移动商城第二篇(品牌管理模块)【文件上传、数据校验、CRUD】
- 手把手在亚马逊EC2上搭建Keras GPU
- 移动商城第三篇(商品管理)【查询商品、添加商品】
- 移动商城第四篇(商品管理)【添加商品续篇、商品审核和上下架、前台展示、后台筛选】
- 移动商城第五篇(用户模块)【用户登陆、回显用户、拦截器、收货地址】
- 移动商城第六篇【单品查询、静态化页面】
- 移动商城第七篇【购物车增删改查、提交订单】
- Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】
- OFTest(一):如何忽略一些字段在端口poll报文
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面向对象视角下的前端工程体系
- 使用 Python破解大众点评字体加密(SVG反爬虫)
- Python爬虫练习:爬取高清4K桌面壁纸
- 爬取B站18000条《黑神话:悟空》实机演示弹幕,做成词云
- Python爬虫实战:自动化登录网站,爬取商品数据
- 符合自己的工作难找?取招聘网站数据,让你找到心仪的工作
- 虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
- Python爬取NBA虎扑球员数据
- 发现一个好看的手机壁纸网站,撸代码的手已经饥渴难耐了
- 手把手用python教你拿即时的卫星影像装饰你的桌面
- PyCharm2019亲测破解方式
- :: 是什么语法?
- 支付宝二面:Mybatis接口Mapper内的方法为啥不能重载吗?我直接懵逼了...
- Windows系统中使用Linux命令(可以批量下载Modis数据)
- Python制作桑基图(我承认我低估了这个教程)