laravel框架之模型

介绍

        MVC模式中的Model模型,就是一个快速操作数据库(准确的说是对应的数据表,一个模型对应一个数据表)的方法,可以利用模型加上一些自己想要的操作对数据表进行快速操作。如查找特定的记录,增删查改都可。很多语言(Java、Go)都会提供Model的封装,Java有Hibernate,Go的Gin框架的Gorm等,这些封装的提供了接口方法来实现MVC程序逻辑。laravel框架提供的一套Model机制,很多方面值得学习,模型是laravel框架很重要的基础,Eloquent ORM组件提供了模型定义、CRUD、软删除、修改器等Api方法,还有模型事件。模型的封装好处是映射了底层数据库的数据结构、关联关系,提供给逻辑代码调用,并进行了一些优化,有时比直接调用数据库进行sql语句查询更加合理、结构化、性能优化;模型事件机制提取出事件处理、事件监听,使程序逻辑解耦,层次更加清晰。

参考

Laravel 使用artisan命令 创建数据库表,实体类和controller https://blog.csdn.net/chujianbi7142/article/details/100894653

实现

模型定义

所有的 Eloquent 模型都继承至 Illuminate\Database\Eloquent\Model 类。我们创建一个 test 表的模型:
# php artisan make:model Models/Test
use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    //启用软删除
    use SoftDeletes;
    //表名的设置 不是必须 但是laravel会默认给模型相关表加复数s  tests
    protected $table = 'test';
    //主键设置
    protected $primaryKey = "u_id";
    //主键的类型
    protected $keyType = "string";
    //主键是否自增
    public $incrementing = true;
    //自动时间戳
    public $timestamps = false;
    #定义属性字段的默认值
    protected $attributes = ['password'=>'123456'];
    #字段放行 允许对 name 和 email 字段操作
    protected $fillable = ['name','email'];
    #字段拦截 不允许对 update_time 字段操作
    protected $guarded = ['update_time'];
    //自定义时间戳字段名
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';
    //时间戳格式设置
    protected $dateFormat = 'U';
    //自定义数据库连接
    protected $connection = "yunyan";
}

上述模型参数给出了一些常用的,可以参考。

我们使用如下指令,生成建表语句(也可以自行创建)

# php artisan make:migration create_test_table --create=test

在database/migrations目录下自动生成建表语句xxx_create_test_table.php

class CreateTestTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('test', function (Blueprint $table) {
            $table->id();
            //这是我们自定义添加的字段
			$table->string('name');
            $table->string('email')->unique();
			//上面是我们自定义添加的字段
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('test');
    }
}

然后我们再执行指令,在数据库中创建表 

# php artisan migrate

 注:此指令会自动读取databse/*.php,根据定义的建表字段规则,创建新表,删除旧表,进行数据库迁移,这里要注意看看目录下的文件是否和数据库中已存在表。

执行成功后自动生成与建表语句对应的表。

CRUD功能

此处给出一个模型的新增表的一个简单调用例子,其他删除、修改功能不在赘述。

控制器

# php artisan make:controller ModelController

自动生成Models/ModelController.php文件

class ModelController extends Controller
{
    public function add() {
        $test = new Test([
            'name' => '张三',
            'email'=>'[email protected]',
        ]);
        $test->save();
        return $test;
    }
}

路由

routes/api.php


Route::get('/test/add', "ModelController@add");

浏览器访问:http://ip:port/api/test/add

软删除

此处需要在模型定义中加:use SoftDeletes;

控制器

class ModelController extends Controller
{
...
public function delete($id){
        $test = Test::find($id);
        $test->delete();
//$test->forceDelete();  //永久删除
        return $test;
    }

注:真删除就调用 forceDelete()即可。

 路由

Route::get("/test/delete/{id}","ModelController@delete")->name("model.delete");

浏览器访问:http://{ip:port}/api/test/delete/4

 查看表数据记录

发现删除操作记录打上了deleted_at的时间标记,并没有真正删除。

修改器

      修改器 是当我们对模型中的特定字段进行修改操作时,会自动触发修改器。在上面我们有向数据库添加数据,当我们获取到的数据需要经过处理之后才能保存到数据库,那么我们还需要在控制器中多写入一些代码,例如密码的加密,这个时候我们可以尝试使用修改器来对所有需要保存到数据库的密码进行加密。
模型类Test修改,增加相关代码如下:
class Test extends Model
{
...
# 修改器
    public function setPasswordAttribute($password) {
        $password = md5($password);# encrypt 函数是 laravel 提供的一个加密函数
        $this->attributes['password'] = $password; # 所有的字段保存在 $attributes 属性中
    }

控制器

class ModelController extends Controller
{
...
 //修改密码
    public function modiPwd($id,$password){
        $test = Test::find($id);
        $test['password']=$password;
        $test->save();
        return $test;
    }

路由

Route::get("/test/modiPwd/{id}/{password}","ModelController@modiPwd")->name("model.modiPwd"); # 修改密码

浏览器访问:http://{ip:port}/api/test/modiPwd/8/886644

查看数据表记录

发现密码已经修改为密文了

事件

       什么是事件?学习是一个事件、敲代码是一个事件、玩手机也是一个事件,事件是一个比较广泛的的名词,他可以代表所做的一个动作。和事件一起出现的就是监听器了,其作用是用来监听你所做的事情,用来对你的行为做后续处理。 例如, “你在学校上课学习,班主任老师会时不时偷偷在窗口看你们。当你忍不住摸出手机看小说,班主任则会进来没收你的手机。这里看手机是一个事件,该事件发生之后监听器就会执行,这里执行的行为就是没收手机“。这个例子很形象说明了事件机制。

普通事件

需求场景:我们模拟一个保存事件,观察事件监听、事件处理的情况。

1)建立事件,指令如下:

# php artisan make:event TestSaving

 

 

2)建立事件监听器,指令如下: 

# php artisan make:listener TestListeners

 

class TestListeners
{
...
public function handle($event)
    {
        dump('测试事件监听到正在触发...');
    }

3)生成事件及监听器

 

在事件服务提供者中注册事件及监听器,代码如下:

class EventServiceProvider extends ServiceProvider
{
...
    protected $listen = [
        ...
        //自定义事件
        'App\Events\TestSaving' => [
            'App\Listeners\TestListeners'
        ]
    ];

生成事件及监听器,指令如下: 

 
#  php artisan event:generate
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== 

4)事件分发

控制器

 

class ModelController extends Controller
{
...
//事件监听处理
    public function savingEvent(){
//        用于触发事件
        event(new TestSaving());
        return "正在触发保存...";
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

路由 

Route::get("/test/savingEvent","ModelController@savingEvent")->name("model.savingEvent");
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
浏览器访问:http://{ip:port}/api/test/savingEvent

 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

模型事件

      模型事件是专门针对模型而额外添加的功能,模型事件基于上面的普通事件的  1 2 3 步,主要区别在于事件分发的区别。
模型类Test中需要在 $dispatchesEvents 属性添加 事件,如下:
class Test extends Model
{
    protected $dispatchesEvents = [
        'saving' => TestSaving::class, 
    ];
...
需要注意的是事件的 key 是允许你挂接到模型生命周期的如下节点。 Eloquent 模型触发几个事件:
  • retrieved:获取到模型实例后触发
  • creating:插入到数据库前触发
  • created:插入到数据库后触发
  • updating:更新到数据库前触发
  • updated:更新到数据库后触发
  • saving:保存到数据库前触发(插入/更新之前,无论插入还是更新都会触发)
  • saved:保存到数据库后触发(插入/更新之后,无论插入还是更新都会触发)
  • deleting:从数据库删除记录前触发
  • deleted:从数据库删除记录后触发
  • restoring:恢复软删除记录前触发
  • restored:恢复软删除记录后触发

我们再浏览器访问接口:http://ip:port/api/test/add  

发现上图,在增加保存记录时,已经真正触发了保存事件saving。

 

模型关联

 

一对一

 

反向关联

 

一对多

 

多对多

 

 

 

 

Guess you like

Origin blog.csdn.net/yan_dk/article/details/117999450