【Laravel】Laravel中的数据库操作
定义模型的命令:bash代码解读复制代码php artisan make:model 模型名新增模型在模型中指定表名:Laravel 自动将 Member 模型名转换为表名,并使用复数形式,即 members。也可以在模型中使用$table 属性来指定表名。php代码解读复制代码:设置主键的名称,默认值为 id,如果主键名称有误,会导致程序出错。:是否自动维护时间戳,默认为 true。
1.数据库的创建与配置
1.1 创建数据库
-
终端进入数据库
bin
目录bash
代码解读
复制代码
cd D:\phpstudy_pro\Extensions\MySQL5.7.26\bin
-
使用账号登录数据库
bash
代码解读
复制代码
mysql -u root -p
-
创建数据库并插入测试数据
bash
代码解读
复制代码
# ① 创建数据库,并使用USE选择数据库 CREATE DATABASE `laravel`; USE `laravel`; # ② 在数据库中创建member数据表 CREATE TABLE `member` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(32) NOT NULL DEFAULT '', `age` TINYINT UNSIGNED NOT NULL DEFAULT 0, `email` VARCHAR(32) NOT NULL DEFAULT '' ) ENGINE=InnoDB CHARSET=utf8mb4; # ③ 在member数据表中插入测试数据 INSERT INTO `member` VALUES (1, 'tom', 20, 'tom@laravel.test');
1.2 Laravel链接数据库
-
数据库的配置文件是
config\database.php
数据库大部分配置都是通过env()函数进行加载的,我们直接修改.env
文件就ok,但是在实际使用中需要在文件中写文件里面bash
代码解读
复制代码
'mysql' => [ 'driver' => 'mysql', // 数据库驱动 'host' => env('DB_HOST', '127.0.0.1'), // 主机名或IP 'port' => env('DB_PORT', '3306'), // 端口 'database' => env('DB_DATABASE', 'forge'), // 数据库名 'username' => env('DB_USERNAME', 'forge'), // 用户名 'password' => env('DB_PASSWORD', ''), // 密码 'unix_socket' => env('DB_SOCKET', ''), // socket路径 'charset' => 'utf8mb4', // 字符集 'collation' => 'utf8mb4_unicode_ci', // 校对集 'prefix' => '', // 数据库表前缀 'strict' => true, // 使用严格模式 'engine' => null, // 指定存储引擎 ],
-
在
.env
文件里面找到数据库配置,对配置进行修改bash
代码解读
复制代码
DB_CONNECTION=mysql # 数据库 DB_HOST=127.0.0.1 # 链接地址 DB_PORT=3306 # 端口 DB_DATABASE=laravel # 数据库名 DB_USERNAME=root # 用户名 DB_PASSWORD=123456 # 密码
2. 使用DB类操作数据库
Laravel中,DB类对常用的数据库操作进行了封装,可以完成数据的添加、修改、查询和删除等操作,对于一些复杂的需求,也可以手写SQL让DB类执行
2.1 DB类的使用步骤
-
在控制器引入 DB
php
代码解读
复制代码
//TestController <?php ...... use DB; //引入 ....
-
在TestController中编写一个database()方法,用于测试DB类
php
代码解读
复制代码
public function database() { $data = DB::table('member')->get(); foreach ($data as $v) { dump($v->id . '-' . $v->name); } }
-
将database()方法添加到路由
php
代码解读
复制代码
Route::get('test/database', 'TestController@database');
-
通过浏览器访问
成功查询到
Member
数据
2.2 添加数据
使用DB类为数据表添加数据有两个常用的方法,分别是insert()和insertGetId()
insert()方法:返回值为 true 或 false,表示是否添加成功
insertGetId()方法:返回值为自动增长的 id
-
单条数据添加
php
代码解读
复制代码
$data = [ 'name' => 'and', 'age' => '22', 'email' => 'tom@laravel.test' ]; // insert()方法 dump(DB::table('member')->insert($data)); // insertGetId()方法 dump(DB::table('member')->insertGetId($data));
-
使用insert( )方法还可以同时添加多条数据
php
代码解读
复制代码
$data = [ ['name' => 'tom', 'age' => '23', 'email' => 'tom@laravel.test'], ['name' => 'jim', 'age' => '24', 'email' => 'jim@laravel.test'], ['name' => 'tim', 'age' => '25', 'email' => 'tim@laravel.test'], ]; // insert()方法 dump(DB::table('member')->insert($data));
2.3 修改数据
-
修改数据可以用update()、increment()或decrement()方法来实现,这些方法的返回值是受影响的行数。
- update()方法用于修改指定的字段;
- increment()方法用于对数字进行递增;
- decrement()方法用于对数字进行递减。
php
代码解读
复制代码
// 将表中所有记录的name字段的值都改为tom $data = ['name' => 'tom']; dump(DB::table('member')->update($data)); // 将表中所有记录的age字段的值都加1 dump(DB::table('member')->increment('age')); // 将表中所有记录的age字段的值都减1 dump(DB::table('member')->decrement('age')); // 将表中所有记录的age字段的值都加5 dump(DB::table('member')->increment('age', 5)); //将表中所有记录的age字段的值都减5 dump(DB::table('member')->decrement('age', 5));
-
实际开发中,通常会用WHERE条件限定要操作的记录。因此,在调用update()、increment()或decrement()方法前,可以先调用where()方法传递一些WHERE条件
php
代码解读
复制代码
$data = [ // 添加单条数据 'name' => 'adler', 'age' => '66', 'email' => 'adler@laravel.test' ]; // 参数形式1:where(字段名, 运算符, 字段值) DB::table('member')->where('id', '=', '1')->update($data); // 参数形式2:where(字段名, 字段值),使用“=”运算符 DB::table('member')->where('id', '1')->update($data); // 参数形式3:where([字段名 => 字段值]),使用“=”运算符,支持多个字段,AND关系 DB::table('member')->where(['id' => 1])->update($data);
-
有多个 WHERE 条件时:
在 where()的后面连续调用 where()表示 AND 条件
在 where()的后面连续调用 orWhere()表示 OR 条件
php
代码解读
复制代码
$data = [ // 添加单条数据 'name' => 'adler', 'age' => '66', 'email' => 'adler@laravel.test' ]; // where()表示AND,即 “WHERE id=1 AND name='tom'” DB::table('member')->where(['id' => 6])->where(['name' => 'tom'])->update($data); // orWhere()表示OR,即“WHERE id=1 OR name='tom'” DB::table('member')->where(['id' => 1])->orWhere(['name' => 'tom'])->update($data);
-
where()和orWhere()方法也可以用于查询数据、删除数据的操作中。
2.4 查询数据
-
查询多行数据
使用get()方法获取多行数据,返回值是集合(Collection),通过foreach取出里面的每一条记录。
由于每一条记录都是一个对象,需要用对象访问属性的方式来获取指定字段的值。
php
代码解读
复制代码
//查询全部 $data = DB::table('member')->get(); foreach ($data as $v) { echo $v->id . '-' . $v->name . '<br>'; } // 指定查询条件 DB::table('member')->where('id', '<', 3)->get(); foreach ($data as $v) { echo $v->id . '-' . $v->name . '<br>'; }
-
查询单行数据
使用first()方法获取单行数据,返回值是对象,通过访问对象的属性来获取字段的值。
php
代码解读
复制代码
// 查询id为1的记录 $data = DB::table('member')->where('id', '1')->first(); // 输出id字段的值 dump($data->id);
-
查询指定字段的值
调用get()、first()方法时通过数组参数传入要查询的字段。
php
代码解读
复制代码
// 获取name和email两个字段,返回多条记录 $data = DB::table('member')->get(['name', 'email']); dump($data);
php
代码解读
复制代码
// 获取name和email两个字段,返回一条记录 $data = DB::table('member')->first(['name', 'email']); dump($data);
使用select()方法指定要查询的字段。
php
代码解读
复制代码
// 获取name、email两个字段 $data = DB::table('member')->select('name', 'email')->get(); dump($data);
php
代码解读
复制代码
// 获取name、email两个字段(数组参数) $data = DB::table('member')->select(['name', 'email'])->get(); dump($data);
php
代码解读
复制代码
// 获取name字段,并设置别名为username $data = DB::table('member')->select('name as username')->get(); dump($data);
php
代码解读
复制代码
// 不解析字段,直接传入字符串作为字段列表 $data = DB::table('member')->select(DB::raw('name,age'))->get(); dump($data);
-
查询某个字段的值 使用value()方法返回某个字段的值,该方法的参数是字段名,返回结果是该字段的值。
php
代码解读
复制代码
// 查询id为1的记录,返回name字段的值 $name = DB::table('member')->where('id', '1')->value('name'); // 输出结果 dump($name);
-
排序 使用orderBy()方法进行排序,第1个参数指定排序字段,第2个参数指定排序规则,包括asc(升序)或desc(降序)。
php
代码解读
复制代码
$data = DB::table('member')->orderBy('age', 'desc')->get(); dump($data);
-
分页 使用limit()方法和offset()方法实现分页,limit()方法指定每页显示的记录数,offset()方法设置开始的偏移量。
php
代码解读
复制代码
$data = DB::table('member')->limit(3)->offset(2)->get(); dump($data);
limit(3)和 offset(2)相当于 SQL 语句中的“LIMIT 3, 2”。
2.5 删除数据
- 使用delete()方法删除指定的记录,返回值为删除的行数
php
代码解读
复制代码
// 删除id为1的记录,返回值为删除的行数 $res = DB::table('member')->where('id', '1')->delete(); dump($res);
- 使用truncate()方法清空整个数据表,相当于SQL中的“TRUNCATE member”
php
代码解读
复制代码
// 清空数据表(相当于SQL中的“TRUNCATE member”) DB::table('member')->truncate();
2.6 执行SQL
通过DB类直接执行SQL语句:
php
代码解读
复制代码
// 执行SELECT语句,返回结果集 $data = DB::select('SELECT * FROM `member`'); dump($data); // 执行INSERT语句,返回true或false DB::insert('INSERT INTO `member` SET `name`=\'tom\''); // 执行UPDATE语句,返回受影响的行数 DB::update('UPDATE `member` SET `age`=\'20\' WHERE `name`=\'tom\''); // 执行DELETE语句,返回受影响的行数 DB::delete('DELETE FROM `member` WHERE `name`=\'tom\''); // 执行其他语句,如CREATE TABLE,返回true或false DB::statement('CREATE TABLE `test` (`id` INT)');
2.7 链接查询
步骤:
- 创建文章表和作者表,每一篇文章都有一个作者,在文章表中需要保存作者的 id。
- 编写 SQL 语句查询文章,把文章的作者也查询出来。
创建文章表和作者表的 SQL 语句:
php
代码解读
复制代码
# 文章表 CREATE TABLE `article` ( `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `article_name` VARCHAR(50) NOT NULL COMMENT '文章名称', `author_id` INT UNSIGNED NOT NULL COMMENT '作者id' ) DEFAULT CHARSET=utf8mb4; # 作者表 CREATE TABLE `author` ( `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `author_name` VARCHAR(20) NOT NULL COMMENT '作者名称' ) DEFAULT CHARSET=utf8mb4; # 测试数据 INSERT INTO `article` VALUES (1, '欢迎使用Laravel', 1); INSERT INTO `author` VALUES (1, '张三');
链接查询
php
代码解读
复制代码
SELECT t1.`id`, t1.`article_name`, t2.`author_name` FROM `article` AS t1 LEFT JOIN `author` AS t2 ON t1.`author_id`=t2.`id`;
在控制器中多表查询‘
php
代码解读
复制代码
$data = DB::table('article AS t1')->select( 't1.id', 't1.article_name AS article_name', 't2.author_name AS author_name' )->leftjoin( 'author AS t2', 't1.author_id', '=', 't2.id' )->get(); foreach ($data as $v) { echo $v->id . '-' . $v->article_name . '-' . $v->author_name; }
3.使用模型操作数据库
3.1 初识模型
Laravel 内置了 Eloquent 模型组件,使用该组件操作数据库。Eloquent 模型采用对象关系映射(Object Relational Mapping,ORM)的设计思想。
ORM:用来在关系型数据库和对象之间做一个映射,它将数据库中的表作为类,表中的记录作为对象,表中的字段作为属性,使用 ORM 操作数据库和操作对象类似
- 普通查询和使用 Eloquent 模型查询的区别:
php
代码解读
复制代码
// 普通查询方式 $sql = 'SELECT id,name FROM member WHERE id = 1'; $data = DB::select($sql); $username = $data[0]->name; // Eloquent模型查询 $member = Member::find(1); $username = $member->name;
- 使用 Eloquent 模型操作数据库的优点:
-
- 不需要书写 SQL 语句,直接使用已经封装好的数据库操作就可以查询数据。
- 数据模型都统一定义,容易更新和维护,也利于代码重用。
- ORM 有封装好的工具,很多功能都可以自动完成,比如预处理、事务等。
- 业务代码比较简单,代码量少,语义性好,容易理解。
3.2 定义模型
定义模型的命令:
bash
代码解读
复制代码
php artisan make:model 模型名
新增模型
在模型中指定表名:Laravel 自动将 Member 模型名转换为表名,并使用复数形式,即 members。也可以在模型中使用$table 属性来指定表名。
php
代码解读
复制代码
class Member extends Model { protected $table = 'member'; }
模型类中的其他可选属性:
protected $primaryKey
:设置主键的名称,默认值为 id,如果主键名称有误,会导致程序出错。public $timestamps
:是否自动维护时间戳,默认为 true。设为 true 时,模型会自动维护表中的 created_at(创建时间)和 updated_at(更新时间)字段。protected $fillable
:允许某些字段可以被添加或修改,格式为一维数组形式。使用模型的create()方法添加数据时,需要设置$fillable。protected $guarded
:禁止某些字段被添加或修改,与$fillable 只能二选一。
public $timestamps
是默认开启的,因此需要为数据表添加created_at和updated_at字段
关闭自动维护时间戳
php
代码解读
复制代码
public $timestamps = false;
3.3 使用模型
在控制器文件中引入模型的命名空间:
php
代码解读
复制代码
use App\Member;
添加上述代码后,就可以通过 Member 类来使用模型了。
模型的使用方式:
- 静态调用
- 实例化模型
php
代码解读
复制代码
// 方式1:静态调用 Member::get(); // 方式2:实例化模型 $member = new Member(); $member->get();
3.4 模型添加数据
-
save()方法
使用方式:先实例化模型,为模型的属性赋值,模型的属性对应数据表的字段,赋值完成后调用 save()方法保存。
php
代码解读
复制代码
$member=new Member(); $member->name = 'server'; $member->age='21'; $member->email = 'server@laraver.net'; dump($member->save()); dump($member->id);
-
fill()方法
以数组的方式填充数据,数组的键名对应字段名,填充后调用 save()方法保存。
php
代码解读
复制代码
$data = ['name' => 'fill', 'age' => '20', 'email' => 'fill@laravel.test']; $member = new Member(); $member->fill($data); $member->save();
-
create()方法
在实例化模型的同时为模型填充数据,调用 save()方法保存。
php
代码解读
复制代码
$data = ['name' => 'tom', 'age' => '20']; $member = Member::create($data); $member->save();
3.5 模型查询数据
-
find()方法
根据主键查询记录,如果数据不存在返回 null
php
代码解读
复制代码
// 查询主键为4的记录,返回模型对象 $member = Member::find(4); dump($member->name); // 获取name字段的值 // 添加查询条件,返回name和age字段 $member = Member::where('name', 'tom')->select('name', 'age')->find(1); dump($member); // 查询主键为1、2、3的记录,返回对象集合 $members = Member::find([1, 2, 3]); dump($members);
-
get()方法
与 DB 类的 get()方法类似,两者的返回结果都是对象集合,但对象的类型不同。
模型的 get()方法返回的是模型对象的集合。
DB 类的 get()方法返回的是普通对象的集合。
php
代码解读
复制代码
// 模型的get()方法 $members = Member::where('id', '1')->get(); dump(get_class($members[0])); // 输出结果:"App\Member" // DB类的get()方法 $members = DB::table('member')->where('id', 1)->get(); dump(get_class($members[0])); // 输出结果:"stdClass"
-
all()方法
查询表中所有的记录,返回模型对象集合,all()方法前不能调用 where()、select()方法。
php
代码解读
复制代码
// 查询所有记录,返回对象集合 $members = Member::all(); dump($members);
php
代码解读
复制代码
// 查询所有记录的name和age字段,返回对象集合 $members = Member::all(['name', 'age']); dump($members);
3.6 模型修改数据
使用模型修改数据的两种方式:
- 先查询后保存,通常用于在保存前进行一些操作。
- 直接修改
php
代码解读
复制代码
// 用模型进行数据查询 // 方式1:先查询后保存 $member = Member::find(3); if ($member) { $member->name = 'test1'; $member->email = 'test1@laravel.test'; $member->save(); dump('修改成功'); } else { dump('修改失败:记录不存在'); } // 方式2:直接修改 Member::where('id', 6)->update(['name' => 'test2', 'age' => 30]);
3.7 模型删除数据
php
代码解读
复制代码
// 先查询后删除数据 $member = Member::find(4); if ($member) { $member->delete(); dump('成功'); } else { dump('修改失败'); }
php
代码解读
复制代码
//直接删除 Member::where('id', 5)->delete(); dump($data);
4.关联模型的使用
4.1 一对一
4.2 一对多
一位作者可以发表多篇文章,作者和文章就是一对多的关系。
在Author模型建立一对多关联:使用hasMany()方法建立一对多关系
php
代码解读
复制代码
public function article() { return $this->hasMany('App\Article', 'author_id', 'id'); }
在TestController的test()方法中查询数据:
php
代码解读
复制代码
public function test() { $data = \App\Author::all(); foreach ($data as $key => $value) { echo '作者名称:' . $value->author_name . '<br>'; foreach ($value->article as $k => $v) { echo $v->article_name . '<br>'; } } }
4.3 多对一
将一对多的关系反过来,就是多对一的关系,使用belongsTo()方法建立多对一关系。
修改Article模型的author()方法,建立多对一关联:
php
代码解读
复制代码
public function author() { return $this->belongsTo('App\Author', 'author_id', 'id'); }
在TestController的test()方法中查询数据:
php
代码解读
复制代码
public function test() { $data = \App\Article::all(); foreach ($data as $key => $value) { echo '文章id:' . $value->id . '<br>'; echo '文章名称:' . $value->article_name . '<br>'; echo '作者名称:' . $value->author->author_name; } }
4.4 多对多
一篇文章有多个关键词,一个关键词可以被多个文章使用,那么文章和关键词就是多对多的关系。
多对多可以拆分成两个一对多关系,两个一对多关系需要借助第3张表(中间表)来建立关系。
创建关键词表和中间表:
php
代码解读
复制代码
# 创建关键词表 CREATE TABLE `keyword` ( `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `keyword` VARCHAR(255) NOT NULL COMMENT '关键词' ) DEFAULT CHARSET=utf8mb4; # 创建中间表,保存文章和关键词的关联 CREATE TABLE `article_keyword` ( `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `article_id` INT UNSIGNED NOT NULL COMMENT '文章id', `keyword_id` INT UNSIGNED NOT NULL COMMENT '关键词id' ) DEFAULT CHARSET=utf8mb4;
1. 使用文章模型查询关键字
在文章模型中使用belongsToMany()方法建立多对多关联。
php
代码解读
复制代码
public function keyword() { return $this->belongsToMany( 'App\Keyword', 'article_keyword', 'article_id', 'keyword_id' ); }
- 第1个参数表示被关联模型的命名空间。
- 第2个参数表示中间表的表名。
- 第3个参数表示中间表中当前模型的关系字段。
- 第4个参数表示中间表中被关联模型的关系字段。
在TestController的test()方法中查询数据:
php
代码解读
复制代码
public function test() { $data = \App\Article::all(); foreach ($data as $key => $value) { echo '文章名称:' . $value->article_name . '<br>'; echo '关键词:'; foreach ($value->keyword as $k => $v) { echo $v->keyword . ' '; } echo '<hr>'; } }
2. 使用关键字查询数据
在关键词模型中建立多对多关联:
php
代码解读
复制代码
public function article() { return $this->belongsToMany('App\Article', 'article_keyword', 'keyword_id', 'article_id'); }
在TestController的test()方法中查询数据:
php
代码解读
复制代码
public function test() { $data = \App\Keyword::all(); foreach ($data as $key => $value) { echo '关键词:' . $value->keyword . '<br>'; echo '相关文章:'; foreach ($value->article as $k => $v) { echo $v->article_name . ' '; } echo '<hr>'; } }
5.数据表的迁移和填充
5.1 数据表迁移
数据表迁移共分为两步:
-
第1步是创建迁移文件,
-
第2步是执行迁移文件。
迁移文件的保存目录为database\migrations,命名方式为“时间版本_create_表名_table.php”。
-
创建迁移文件
创建迁移文件命令:
bash
代码解读
复制代码
php artisan make:migration 迁移文件名
创建paper表迁移文件命令:
bash
代码解读
复制代码
php artisan make:migration create_paper_table
paper表对应的迁移文件部分示例代码:
php
代码解读
复制代码
public function up() { Schema::create('paper', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } function down() { Schema::dropIfExists('paper'); }
paper表的字段要求:
- id:表的主键,自动增长。
- paper_name:试卷名称,VARCHAR(100)类型,不允许重复值。
- total_score:试卷总分,TINYINT类似,默认为0。
- start_time:试卷开始考试时间,INT类型(保存时间戳)。
- duration:考试时间长度,单位为分钟,TINYINT类型。
- status:试卷是否启用,TINYINT类型,1表示启用,2表示禁用,默认为1。
- created_at:创建时间,TIMESTAMP类型,默认为NULL。
- updated_at:更新时间,TIMESTAMP类型,默认为NULL。
paper表字段对应的迁移代码:
php
代码解读
复制代码
Schema::create('paper', function (Blueprint $table) { $table->increments('id')->comment('主键'); $table->string('paper_name', 100)->comment('试卷名称')->unique(); $table->tinyInteger('total_score')->default(0)->comment('试卷总分'); $table->integer('start_time')->comment('考试开始时间'); $table->tinyInteger('duration')->comment('考试时长'); $table->tinyInteger('status')->default(1)->comment('状态'); $table->timestamps(); });
-
执行迁移文件
在项目中第一次执行迁移文件时,需要安装迁移,安装迁移命令:
bash
代码解读
复制代码
php artisan migrate:install
安装迁移后,生成migrations表保存迁移记录,migrations表字段:
- id:表的主键,用来唯一标识每条记录。
- migration:用来记录执行过的迁移文件。
- batch:用来记录批次,每次执行迁移命令,批次就会加1。如果在一次迁移命令中迁移了两张表,那么这两张表就属于同一个批次。
执行迁移命令:
bash
代码解读
复制代码
php artisan migrate
回滚迁移命令:
bash
代码解读
复制代码
php artisan migrate:rollback
5.2 数据库填充
-
创建填充文件
填充文件又称为填充器、种子文件,创建命令:
bash
代码解读
复制代码
php artisan make:seeder 填充器名称
创建paper表填充文件:
bash
代码解读
复制代码
php artisan make:seeder PaperTableSeeder
PaperTableSeeder.php填充文件部分示例代码:
php
代码解读
复制代码
<?php use Illuminate\Database\Seeder; class PaperTableSeeder extends Seeder { public function run() { // } }
在run()方法中编写填充代码:
php
代码解读
复制代码
public function run() { DB::table('paper')->insert([ [ 'paper_name' => 'PHP期末复习题', 'total_score' => 100, 'start_time' => time() + 86400, 'duration' => 120, 'status' => 1 ], ……(添加更多数据) ]); }
-
执行填充文件
执行PaperTableSeeder.php填充文件的命令:
bash
代码解读
复制代码
php artisan db:seed --class=PaperTableSeeder
更多推荐
所有评论(0)