Eloquent 模型

默认继承use Illuminate\Database\Eloquent\Model类。

数据表名称与模型名称约定:

数据库的表名一般使用“蛇形命名法”命名。蛇形命名法要求单词小写,单词之间用_下划线连接,且名称是复数。

与之对应的模型名称,则使用“帕斯卡法“命名,即单词头一字母都大写。

如果不是按以上约定,则需指明对应的数据表:

class Flight extends Model
{
/**
* 与模型关联的数据表
*
* @var string
*/
protected $table = 'myflights';
}

主键:

模型默认数据表用id字段作主键,并且是递增整数类型。这些可以自定义:

class Flight extends Model
{
/**
* 与模型关联的数据表
*/
protected $table = 'my_flights'; protected $primaryKey='mid'; //自定义主键字段 protected $keyType = 'string'; //自定义主键类型为字串 public $incrementing = false; //主键非自增型
}

时间截:

模型默认存在created_at 和 updated_at两字段,可设定$timestamps不需两字段:

class Flight extends Model
{
/**
* 该模型是否被自动维护时间戳
*/
public $timestamps = false;
}

$dateFormat属性可自定义时间截格式存储在数据表的格式:

class Flight extends Model
{
/**
* 模型的日期字段的存储格式
*/
protected $dateFormat = 'U';
}

自定义时间截字段名:

<?php

class Flight extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
}

自定义数据库连接:

class Flight extends Model
{
/**
* 此模型的连接名称。
*/
protected $connection = 'connection-name';
}

模型查询:

use App\Flight;

$flights = App\Flight::all();   //查询所有数据

foreach ($flights as $flight) {
echo $flight->name;
} $flights = App\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get(); //有条件地查询数据

all和get方法返回 Illuminate\Database\Eloquent\Collection实例。

如果查询大批量数据,可使用chunk,可节省内存:

Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});

或使用游标方法cursor大幅度减少内存的使用:

foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
//
}

查询单条数据:

// 通过主键取回一个模型...
$flight = App\Flight::find(1); // 取回符合查询限制的第一个模型 ...
$flight = App\Flight::where('active', 1)->first(); //如果找不到模型则抛出异常
//Illuminate\Database\Eloquent\ModelNotFoundException
//自动返回 HTTP 404 响应给用户
$model = App\Flight::where('legs', '>', 100)->firstOrFail();

聚合查询:

$count = App\Flight::where('active', 1)->count();

$max = App\Flight::where('active', 1)->max('price');

数据更新:

save方法:需要先检索一次,再设置要更新的属性再执行save方法,同时updated_at也会自动更新。

update方法:设置where条件,将更新字段以键值对传入update方法。该更新不会触发saved和updated模型事件。

$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save(); //查询一次后再更新 App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]); //设置条件后再批量更新

插入数据:

使用模型创建数据,需先设置$fillable或$guarded属性。两属性只能二选一。

class Flight extends Model
{
/**
* 可以被批量赋值的属性。
* @var array
*/
protected $fillable = ['name'];
} class Flight extends Model
{
/**
* 不可被批量赋值的属性。可定义为空数组,表示所有属性都可以赋值。
* @var array
*/
protected $guarded = ['price'];
}

插入数据的方法:

$flight = App\Flight::create(['name' => 'Flight 10']); //添加新记录并返回已保存的模型实例

$flight->fill(['name' => 'Flight 22']); //已有实例模型可使用fill方法
// 通过 name 属性检索航班,当结果不存在时创建它...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); // 通过 name 属性检索航班,当结果不存在的时候用 name 属性和 delayed 属性去创建它
$flight = App\Flight::firstOrCreate(
['name' => 'Flight 10'], ['delayed' => 1]
); // 通过 name 属性检索航班,当结果不存在时实例化...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
// 通过 name 属性检索航班,当结果不存在的时候用 name 属性和 delayed 属性实例化
$flight = App\Flight::firstOrNew(
['name' => 'Flight 10'], ['delayed' => 1]
); // 如果有从奥克兰飞往圣地亚哥的航班,将价格设为 99 美元
// 如果不存在匹配的模型就创建一个
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);

firstOrCreate:如果查不到该数据,则根据第一参数和第二参数记录创建记录返回保存的模型;

firstOrNew:如果查不到该数据,则根据第一参数和第二参数记录创建新模型,但并未保存数据,需要手动save才可以保存数据;

updateOrCreate:根据第一参数作条件用更新第二参数数据,如果数据不存在则合并两参数创建记录返回保存的模型。

删除模型:

$flight = App\Flight::find(1);
$flight->delete(); //通过查询所得的模型实例进行delete方法删除 //通过主键删除一至多条数据:
App\Flight::destroy(1);
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(1, 2, 3); //通过查询条件批量删除,并返回删除条数
$deletedRows = App\Flight::where('active', 0)->delete();

批量删除时,deleted和deleting模型事件不会被触发。

软删除:

数据表应设置deleted_at字段。模型内引用SoftDeletes trait,并设置deleted_at字段到$dates属性上。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; class Flight extends Model
{
use SoftDeletes; /**
* 需要被转换成日期的属性。
* @var array
*/
protected $dates = ['deleted_at'];
}

设置了软删除的模型,在delete方法会设置deleted_at为当前日期和时间。查询软删除的模型会自动排除被软删除的模型。

if ($flight->trashed()) {
//检查该模型实例是否被软删除
} $flights = App\Flight::withTrashed() //能使用查询包含软删除的数据
->where('account_id', 1)
->get(); $flights = App\Flight::onlyTrashed() //只查询软删除的数据
->where('airline_id', 1)
->get(); $flight->restore(); //恢复被软删除的模型 App\Flight::withTrashed() //批量恢复模型,不会触发任何模型事件
->where('airline_id', 1)
->restore();

软删除模型使用强制删除:

$flight->forceDelete();

查询作用域:

给模型添加查询约束。分全局和本地两种:

全局--每个查询都自动加条件约束;

本地--根据需要调用本地约束。

全局作用域:

首先需实现scope接口类.

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder; class AgeScope implements Scope
{
/**
* 将范围应用于给定的 Eloquent 查询生成器
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
return $builder->where('age', '>', 200);
}
}

如果全局作用域要将字段添加到查询的 select 语句中,则应该使用 addSelect 方法而不是 select,以免替换查询的现有select。

应用全局作用域:

在模型的boot方法使用addGlobalScope方法。

<?php

namespace App;

use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model; class User extends Model
{
/**
* 模型的「启动」方法
*
* @return void
*/
protected static function boot()
{
parent::boot(); static::addGlobalScope(new AgeScope);
}
}

也可以使用闭包定义全局作用域,不必单独定义一个类:

class User extends Model
{
/**
* 模型的「启动」方法
*
* @return void
*/
protected static function boot()
{
parent::boot(); static::addGlobalScope('age', function(Builder $builder) {
$builder->where('age', '>', 200);
});
}
}

删除全局作用域:

User::withoutGlobalScope(AgeScope::class)->get();  //删除指定的作用域

// 删除所有的全局作用域
User::withoutGlobalScopes()->get(); // 删除一些全局作用域
User::withoutGlobalScopes([
FirstScope::class, SecondScope::class
])->get();

本地作用域:

定义通用的约束在需要时使用。定义方法:在模型内定义scope前缀的方法。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
/**
* 限制查询只包括受欢迎的用户。
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
} /**
* 限制查询只包括活跃的用户。
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeActive($query)
{
return $query->where('active', 1);
}
}

使用方法:

$users = App\User::popular()->active()->orderBy('created_at')->get();

动态作用域:

class User extends Model
{
/**
* 限制查询只包括指定类型的用户。
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
} //调用作用域时传参
$users = App\User::ofType('admin')->get();

模型事件:

retrieved --查询触发

creatingcreated--创建触发

updatingupdated--更新触发

savingsaved--创建、更新触发

deletingdeleted--删除触发

restoringrestored--恢复触发

事件指派相应的监控器:

<?php

namespace App;

use App\Events\UserSaved;
use App\Events\UserDeleted;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable
{
use Notifiable; /**
* 模型的事件映射。
*
* @var array
*/
protected $dispatchesEvents = [
'saved' => UserSaved::class, //触发saved事件,调用UserSaved监控器
'deleted' => UserDeleted::class, //触发deleted事件,调用UserDeleted监控器
];
}

也可所有监听放在一个观察器类中:

<?php

namespace App\Observers;
use App\User; class UserObserver
{
/**
* 监听用户创建的事件。
*
* @param User $user
* @return void
*/
public function created(User $user)
{
//
} /**
* 监听用户删除事件。
*
* @param User $user
* @return void
*/
public function deleting(User $user)
{
//
}
}

注册观察器:

<?php

namespace App\Providers;

use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider
{
/**
* 运行所有应用.
*
* @return void
*/
public function boot()
{
User::observe(UserObserver::class);
}

Laravel笔记--Eloquent 模型的更多相关文章

  1. 使用laravel的Eloquent模型获取数据库的指定列

    使用laravel的Eloquent模型获取数据库的指定列   使用Laravel的ORM——Eloquent时,时常遇到的一个操作是取模型中的其中一些属性,对应的就是在数据库中取表的特定列. 如果使 ...

  2. 【laravel】Eloquent 模型事件和监听方式

    所有支持的模型事件 在 Eloquent 模型类上进行查询.插入.更新.删除操作时,会触发相应的模型事件,不管你有没有监听它们.这些事件包括: retrieved 获取到模型实例后触发 creatin ...

  3. laravel 为Eloquent 模型添加replace 和insert ignore 查询功能

    安装:composer require jdavidbakr/replaceable-model 在模型里引入: class model extends Model { ... use \jdavid ...

  4. laravel Eloquent 模型(也就是我本时说的Model)

    laravel的 Eloquent 模型其实就是我们平时说的MVC里Model,只是换了个名字而已~ 1)Eloquent 是啥? Eloquent 本质就一个查询构建器(laravel里叫查询构建器 ...

  5. Laravel 5.1 文档攻略 —— Eloquent:模型关系

    简介 其实大家都知道,数据表之间都是可以关联的,前面讲过了,Eloquent ORM是数据模型操作代替表操作,那么表的关联查询,在Eloquent这里也就是模型间的关联查询,这就是本章的主要内容: E ...

  6. 【Laravel】为Eloquent 模型设置全局作用域和局部作用域进行查询

    全局作用域 所谓「全局作用域」,指的是预置过滤器在注册该「全局作用域」的模型类的所有查询中生效,不需要指定任何额外条件. 以 User 模型类为例,我们在系统中可能只想针对已经验证过邮箱的用户进行操作 ...

  7. ArcGIS案例学习笔记2_2_模型构建器和山顶点提取批处理

    ArcGIS案例学习笔记2_2_模型构建器和山顶点提取批处理 计划时间:第二天下午 背景:数据量大,工程大 目的:自动化,批处理,定制业务流程,不写程序 教程:Pdf/343 数据:chap8/ex5 ...

  8. Django:学习笔记(7)——模型进阶

    Django:学习笔记(7)——模型进阶 模型的继承 我们在面向对象的编程中,一个很重要的的版块,就是类的继承.父类保存了所有子类共有的内容,子类通过继承它来减少冗余代码并进行灵活扩展. 在Djang ...

  9. Django:学习笔记(6)——模型

    Django:学习笔记(6)——模型 快速上手 模型到底是什么呢?我们可以想,如果一张数据表的各个字段可以自动映射到一个类的各个属性,则每条记录对应这个类的一个对象.那我们通过类方法来操作对象(即表记 ...

随机推荐

  1. oracle 同义词synonym

    在A用户下,想访问B用户下的表,一遍需要用 “用户名.表名 ”的格式进行访问.如果想不加用户名,直接访问,需要建同义词. 同义词语法如下: CREATE [PUBLIC] SYNONYM synony ...

  2. Curve 曲线 工具

    最近研究了曲线绘制的工具,主要是2D方程的绘制.综合了许多工具,完成了一下两个脚本. 绘制的工具: using UnityEngine; using System.Collections; using ...

  3. dubbo入门学习笔记之环境准备

    粗略的学完springcloud后由于公司的项目有用到一点dubbo,刚好手头上又有dubbo的学习资料,于是趁机相对系统的学了下duboo框架,今天开始记录下我的所学所悟;说来惭愧,今年之前,作为一 ...

  4. linux-docker下安装禅道全部

    友情提示:按照步骤走,99%的人会安装成功,1%的人可以咨询度娘 64位电脑安装禅道,满足发送邮件功能 第一步: docker ps 查看docker中的容器是否有禅道(docker ps -a    ...

  5. 安装oracle11g client 【INS-30131】执行安装程序验证所需的初始设置失败的解决方法

    今天在服务器(操作系统windows server 2008R2)上安装Oracle11g 客户端,弹出“执行安装程序验证所需的初始设置失败”,如上图.网上找了一些方法,简单整理如下,仅供参考. 问题 ...

  6. python基础15上_迭代器_生成器

    # 迭代器和生成器 # 迭代器: # 双下方法 : 很少直接调用的方法.一般情况下,是通过其他语法触发的 # 可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir ...

  7. RabbitMQ,为应对消息从发送到消费,各个环节消息丢失的解决方案

      1.发送方   为保证消息到达exchange,在这个过程中不丢失.  用事务或者发送方确认机制  见<RabbitMQ实战指南>4.8节 2.为保证消息不会因为到达exchange后 ...

  8. grafana 安装配置

    Grafana安装配置 1.下载安装包 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.3.l ...

  9. xshell连不上虚拟机

    一般都是下边这种情况 查看 虚拟机的ip   ip a 看看是否有IP地址 如果没有的话,win+r 输入services.msc 把这三个服务设为正在运行状态 #虚拟机连不上网 前戏: 查看xshe ...

  10. python程序在命令行执行提示ModuleNotFoundError: No module named 'XXX' 解决方法

    在ide中执行python程序,都已经在默认的项目路径中,所以直接执行是没有问题的.但是在cmd中执行程序,所在路径是python的搜索路径,如果涉及到import引用就会报类似ImportError ...