一、内容介绍:
https://learnku.com/docs/laravel/5.8/eloquent/3931手册
- model 入门
- 模型关联
- 修改器
二、内容讲解:
2.1 : model入门,数据库测试
主要是模型工厂:
创建模型手册:https://learnku.com/articles/6710/laravel-data-filling
创建模型工厂命令:
php artisan make:model Model名称
如果创建的默认名称跟表名不一致,在模型里面必须指定模型对应的table_name 表名,否则会无效,数据表中的主键不是默认的id,也必须在模型中指定主键的id,否则也将无效
2.1:模型的基础使用:
需要讲解的是model与db操作数据库的区别关系,而操作过程中,大部分的方法实际上与db勒差不多,不需要再向db类那样的复杂,理解,(所有curd的操作都封装起来)使用起来也非常方便
而可以侧重于讲解是模型的软删除
- 模型定义
- 模型操作与db的关系
- 软删除
2.1.1:模型定义:
使用的users数据表,是经过数据迁移创建的,laravel自带的数据表结构,
使用的命令:php artisan migrate 迁移数据表(其实就是将迁移文件中的数据结构创建成一张表)
例子:
php artisan migrate
执行该命令会找到app\datbase\migrations目录下的所有文件创建
执行成功后再你的数据库中能看到 users这个表,就是成功了(默认是没有数据的)
什么是模型?怎么定义?
模型的解释:从层级上主要是dao和entity的组合体
dao:操作数据库的方法
entity:是对于一个数据表的抽象描述
而模型是对于数据库操作的一种抽象的描述,相当于是数据表的操作以及实例的抽象表达。
在模型中提供了很多边界的操作数据的方法,相比起db类操作会更加的简单,在之后也更便于维护,所以相比起db会更推荐使用model模型操作数据库。
模型定义命令为:php artisan make:model Models\Users\user(后面指定模型创建的目录路径以及模型名称)
2.1.2:模型操作(查询出来的数据都是对象结果集)
模型与db类的关系
首先需要解释db类,db类对于数据库操作的时候其实也主要是依托于查询构造器,而model也是如此
对于model模型的save、delete、find、all、toArray的使用方式,一定要注意自动时间戳设置,如果不是使用laravel所提供的数据表的话。
# 查询所有数据(sql:select * from table_name)
Users::get();
# 将查询结果集转换为数组(使用 toArray方法转换为数组结果集)
Users::get()->toArray();
# 根据id查询一条结果集(sql:select * from table_name where id = ?)
Users::find(1); 后面参数是主键id值
# 添加数据(第一种方法:)
$userModel = new Users();
// 先指定设置字段的值
$userModel->name = 'test';
$userModel->email = 'qq@qq.com';
// 再调用save保存
// 保存底层会先获取你刚刚设置的那些字段的值,然后添加数据,返回true证明添加成功
$userModel->save();
# 添加数据(第二种方法:使用查询构造器的insert方法)
Users::insert([
'name' => 'test1',
'email' => '123213@qq.com',
'password' => '123213',
]);
# update更新数据(第一种方法,使用查询构造器的update)
$user = Users::where('id', 5)->update(['name' => 'lzy']);
# save 更新数据(第二种方法,使用model更新)
# 使用model更新数据,第一步先获取数据
$userModel = new Users();
$userModel = Users::find(5);
$userModel->name = 'lzy1111';
$user = $userModel->save();
2.1.3:软删除:
什么是软删除:(软删除其实就是一个假操作删除,相当于删除后放在回收站,而并非真正的删除,只是修改一下delete_at 字段为不为空)
软删除的应用场景:(主要是应对与一些重要的数据的时候采用,比如订单信息)
操作之前,确定要操作的表中有 deleted_at 字敦
然后还要再模型中定义以下两个:
class Users extends Model
{
//
use SoftDeletes;
protected $datas = ['deleted_at'];
const DELETED_AT = 'deleted_at';
}
然后实例测试一下:
public function deletes()
{
# 配置好上面的模型操作,才是假操作删除
Users::where('id', 5)->delete();
# 然后查询是否有刚刚删除的数据
Users::all()->toArray();
# 查看包含软删除的数据
Users::withTranshed()->get()->toArray();
# 只查询软删除的数据
Users::onlyTranshed()->get()->toArray();
# 将软删除恢复状态
Users::withTranshed()->where('id', '5')->restore();
# 彻底删除软删除
Users::withTranshed()->where('id', 5)->forceDelete();
}
2.2.4:模型关联:
当然,你的数据表很有可能跟另外一张表相关联,例如:一篇blog文章可能有很多评论,或是一张订单跟下单客户相关联
一对一
一对多
多对多
预载入
这里拿一个例子来测试
从user 表 关联 role表 是一对一的关系(应为一个用户只有一个角色)
从role 表 关联 user 表 是一对多的关系
# 第一步使用命令创建一个user模型
php artisan make:model Models\Users\User
# 再创建一个role模型
php artisan make:model Models\Users\Role
2.2.4.1:模型一对一
用户表关联角色表(一个用户只有一个角色)
public function userRole()
{
/**
* hasOne一对一模型关联
* 1. 关联模型
* 2. 关联模型外键
* 3. 当前模型对于关联模型的外键
*/
return $this->hasOne(Role::class,'id', 'role_id');
}
# 使用
/**
* 一对一模型关联
*/
public function userRoleTest()
{
# 注意:定义的一对一方法调用的时候不需要括号
$result = User::find(5)->userRole;
dump($result);
}
注意:Elonquent 假设对应的关联模型数据库表里,外键名称是基于模型形成,再这个例子里,默认Role模型数据库表会以role_id 作为外键,而我们实际并不是,所以我们需要自己传递参数自定义,(model模型默认的外键主键是id,如果不是id的话,就要指定主键)
$foreignkey 这个参数就是自定义关联模型的关联字段
$localkey 这个参数就是自定义当前模型关联字段
一对多:
我们可以从role模型中关联user模型,一种身份或有多个用户,一对多的关系
例子:
/**
* 一对多操作模型
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function roleUserTest()
{
/**
* hasMany 一对多关系模型
* 1. 关联的模型名称
* 2. 关联模型的关联外键
* 3. 当前模型的关联外键
*/
return $this->hasMany(User::class,'role_id','id');
}
# 使用
public function userRoleTest()
{
# 一对多使用
$result = Role::find(1)->roleUserTest;
dump($result);
}
多对多使用:
多对多关系更为复杂
这里以一个学生,课程,学生关联课程的中间表,
创建一个学生跟课程的中间表以及创建迁移文件
php artisan make:model Models\GrandeStudent -m创建学生表以及创建迁移文件
php artisan make:model Models\Student -m创建课程表以及创建迁移文件
php artisan make:model Models\Grande -m然后再迁移文件目录中指定表的创建结构需要的字段,如下:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// 学生关联课程的中间表
Schema::create('grade_students', function (Blueprint $table) {
$table->bigIncrements('id');
// 学生关联的课程id
$table->integer('grade_id');
// 学生id
$table->integer('student_id');
$table->timestamps();
});
}
- 输入命令迁移文件
php artisan migrate
实例需求,这里直接使用中间表(一个学生可以学习多门课程,一门课程有多个学生学习)
例子:
/**
* 一个学生可以学习多门课程
*/
public function studentToGrande()
{
/**
* 1. 关联模型名称
* 2. 关联中间表模型
* 3. 当前表关联中间表的外键
* 3. 中间表关联当前表的外键
*/
return $this->belongsToMany(Grade::class,GradeStudent::class, 'student_id', 'student_id');
}
# 使用:
/**
* 一对一模型关联
*/
public function userRoleTest()
{
# 多对多使用模型
$result = Student::find(1)->studentToGrande;
dump($result);
}
belongsToManry(‘要关联的模型’, ’ 关联的中间表’, ‘中间关联当前模型外键字段’, '当前表关联的外键字段’)
预载入:
预载入其实就是防止SQL重复查询,例如:你想循环一些数据,每次都是要从新查询一遍才能拿到数据。
预载入实现了不用重复的查询,仅仅只要查询一次结果集就可以使用全部条件
例如:没有使用预加载的数据的时候
下面的结果可想而知,每次都要从新查询结果,这样的执行效率会很低,每次都要重复查询相同的SQL语句
如果使用了预载入的方法,仅仅只要查询出一次SQL语句,就可以查询出所有的结果集
例如:
明显只需要查询一条SQL语句,就可以查询出所有数据
使用到的是laravel里面的with 预载入方法,其实内部是把所有的查询条件拼接成in,再作为查询,