빠른 시작
ㅋㅋ >
- 기본 키
- Timestamp
- 데이터베이스 연결
- 기본 속성 값
- Collection
- 컬렉션 검색
- 모델 검색
- 추가 제약 조건
- 모델 다시 로드
- 청크 결과
- 커서를 사용하여 단일 모델/컬렉션 검색
- "찾을 수 없음" 예외
- 모델 삽입 및 업데이트
- insert
- 일괄 업데이트
- 속성 보호
- 모델 삭제
- 쿼리 범위
- observer
- define observer
Eloquent: 시작하기
Introduction
Laravel의 Eloquent ORM은 아름답고 간결한 ActiveRecord 구현을 제공하여 데이터베이스 상호 작용과 상호 작용합니다. 각 데이터베이스 테이블에는 테이블과 상호 작용하는 데 사용되는 해당 "모델"이 있습니다. 모델을 통해 데이터 테이블의 데이터를 쿼리하고 데이터 테이블에 새 레코드를 삽입할 수 있습니다.
시작하기 전에 config/database.php
에서 데이터베이스 연결을 구성하세요. 데이터베이스 구성에 대한 자세한 내용은 설명서를 확인하세요. config/database.php
中配置数据库连接。更多关于数据库配置的信息,请查看 文档。
模型定义
首先,创建一个 Eloquent 模型。 模型通常在 app
目录中,但你可以根据 composer.json
文件将他们放置在可以被自动加载的任意位置。所有的 Eloquent 模型都继承至 IlluminateDatabaseEloquentModel
类。
创建模型最简单的方法就是使用 make:model
Artisan 命令:
php artisan make:model Flight
如果要在生成模型的时候生成 数据库迁移 ,可以使用 --migration
或 -m
选项:
php artisan make:model Flight --migration php artisan make:model Flight -m
Eloquent 模型约定
现在,我们来看一个 Flight
模型的示例,我们将用它从 flights
app
디렉터리에 있지만 composer.json
파일을 기반으로 자동으로 로드될 수 있는 어디에나 배치할 수 있습니다. 모든 Eloquent 모델은 IlluminateDatabaseEloquentModel
클래스에서 상속됩니다. 🎜🎜모델을 생성하는 가장 쉬운 방법은 make:model
Artisan 명령을 사용하는 것입니다: 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ // }🎜모델 생성 시 데이터베이스 마이그레이션을 생성하려면
--migration<을 사용할 수 있습니다. /code> 또는 -m
옵션: 🎜<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 与模型关联的表名
*
* @var string
*/
protected $table = 'my_flights';
}
🎜🎜🎜🎜웅변적인 모델 규칙
🎜이제 flights
데이터베이스 테이블에서 데이터 정보를 검색하고 저장하는 데 사용할 Flight
모델의 예를 살펴보겠습니다. : 🎜<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 指示模型是否自动维护时间戳
*
* @var bool
*/
public $timestamps = false;
}
🎜🎜데이터 테이블 이름
Flight
모델에 사용할 데이터 테이블을 Eloquent에 알려주지 않는다는 점에 유의하세요. 다른 이름을 명시적으로 지정하지 않는 한, 클래스의 복수형인 "snakes"가 테이블 이름으로 사용됩니다. 따라서 이 경우 Eloquent는 Flight
모델이 flights
데이터 테이블의 데이터를 저장한다고 가정합니다. 모델에 table
속성을 정의하여 사용자 정의 데이터 테이블을 지정할 수 있습니다: Flight
模型使用哪个数据表。 除非明确地指定了其它名称,否则将使用类的复数形式「蛇形命名」来作为表名。因此,在这种情况下,Eloquent 将假设 Flight
模型存储的是 flights
数据表中的数据。你可以通过在模型上定义 table
属性来指定自定义数据表:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 模型日期列的存储格式。
*
* @var string
*/
protected $dateFormat = 'U';
}
主键
Eloquent 也会假设每个数据表都有一个名为 id
的主键列。你可以定义一个受保护的 $primaryKey
属性来重写约定。
此外,Eloquent 假设主键是一个自增的整数值,这意味着默认情况下主键会自动转换为 int
类型。如果您希望使用非递增或非数字的主键则需要设置公共的 $incrementing
属性设置为 false
。如果你的主键不是一个整数,你需要将模型上受保护的 $keyType
属性设置为 string
。
时间戳
默认情况下,Eloquent 预期你的数据表中存在 created_at
和 updated_at
。如果你不想让 Eloquent 自动管理这两个列, 请将模型中的 $timestamps
属性设置为 false
:
<?php
class Flight extends Model{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
}
如果需要自定义时间戳的格式,在你的模型中设置 $dateFormat
属性。这个属性决定日期属性在数据库的存储方式,以及模型序列化为数组或者 JSON 的格式:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 模型的连接名称
*
* @var string
*/
protected $connection = 'connection-name';
}
如果你需要自定义存储时间戳的字段名,可以在模型中设置 CREATED_AT
和 UPDATED_AT
常量的值来实现:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 模型的默认属性值。
*
* @var array
*/
protected $attributes = [
'delayed' => false,
];
}
数据库连接
默认情况下,Eloquent 模型将使用你的应用程序配置的默认数据库连接。如果你想为模型指定一个不同的连接,设置 $connection
属性:
<?php
$flights = App\Flight::all();
foreach ($flights as $flight) {
echo $flight->name;
}
默认属性值
如果要为模型的某些属性定义默认值,可以在模型上定义 $attributes
$flights = App\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get();
기본 키Eloquent는 또한 각각의 각 데이터 테이블에는 id
라는 기본 키 열이 있습니다. 보호된 $primaryKey
속성을 정의하여 규칙을 재정의할 수 있습니다.
또한 Eloquent는 기본 키가 자동 증가하는 정수 값이라고 가정합니다. 이는 기본 키가 기본적으로 int
유형으로 자동 변환된다는 의미입니다. 비증가 또는 숫자가 아닌 기본 키를 사용하려면 공개 $incrementing
속성을 false
로 설정해야 합니다. 기본 키가 정수가 아닌 경우 모델의 보호된 $keyType
속성을 string
으로 설정해야 합니다. Timestamp기본적으로 Eloquent는 created_at
및 updated_at
에 존재할 것으로 예상합니다. Eloquent가 이 두 열을 자동으로 관리하지 않도록 하려면 모델의 $timestamps
속성을 false
로 설정하십시오: $flight = App\Flight::where('number', 'FR 900')->first();
$freshFlight = $flight->fresh();
타임스탬프 형식을 사용자 정의해야 하는 경우 , 모델에서 $dateFormat
속성을 설정하세요. 이 속성은 날짜 속성이 데이터베이스에 저장되는 방식과 모델이 배열 또는 JSON으로 직렬화되는 형식을 결정합니다. 🎜$flight = App\Flight::where('number', 'FR 900')->first();
$flight->number = 'FR 456';$flight->refresh();
$flight->number;
// "FR 900"
🎜 타임스탬프를 저장하기 위해 필드 이름을 사용자 정의해야 하는 경우 CREATED_AT를 설정할 수 있습니다.
모델의 UPDATED_AT
상수 값: 🎜$flights = $flights->reject(function ($flight) {
return $flight->cancelled;
});
🎜🎜데이터베이스 연결🎜🎜기본적으로 Eloquent는 모델은 애플리케이션에서 사용됩니다. 기본 데이터베이스 연결이 구성되었습니다. 모델에 대해 다른 연결을 지정하려면 $connection
속성을 설정하세요. 🎜foreach ($flights as $flight) {
echo $flight->name;
}
🎜🎜🎜🎜기본 속성 값
🎜모델의 일부 속성에 대한 기본값을 정의하려면 다음에서 $attributes
속성을 정의하면 됩니다. 모델: 🎜Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});
🎜🎜🎜 🎜🎜🎜🎜모델 검색🎜🎜모델 및 관련 데이터베이스 테이블을 생성한 후 데이터베이스에서 데이터를 쿼리할 수 있습니다. 각 Eloquent 모델을 관련 데이터 테이블을 더 빠르게 쿼리하는 데 사용할 수 있는 강력한 쿼리 빌더로 생각하세요. 예: 🎜foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
//
}
🎜🎜추가 제약조건
Eloquent의 all
메소드는 모델의 모든 결과를 반환합니다. 각 Eloquent 모델은 쿼리 생성자 역할을 하기 때문에 쿼리 조건을 추가한 다음 get
메서드를 사용하여 쿼리 결과를 얻을 수도 있습니다: all
方法会返回模型中所有的结果。由于每个 Eloquent 模型都充当一个查询构造器,所以你也可以添加查询条件,然后使用 get
方法获取查询结果:
// 通过主键检索一个模型...
$flight = App\Flight::find(1);
// 检索符合查询限制的第一个模型...
$flight = App\Flight::where('active', 1)->first();
{tip} 因为 Eloquent 模型也是查询构造器,所以你也应当阅读 查询构造器可用的所有方法。你可以在 Eloquent 查询中使用这些方法。
重新加载模型
你可以使用 fresh
和 refresh
方法重新加载模型。 fresh
方法会重新从数据库中检索模型。现有的模型实例不受影响:
$flights = App\Flight::find([1, 2, 3]);
refresh
方法使用数据库中的新数据重新赋值现有模型。此外,已经加载的关系会被重新加载:
$model = App\Flight::findOrFail(1);
$model = App\Flight::where('legs', '>', 100)->firstOrFail();
集合
对于 Eloquent 中的 all
和 get
方法可以查询多个结果,返回一个 IlluminateDatabaseEloquentCollection
实例。 Collection
类提供了 很多辅助函数 来处理 Eloquent 结果:
Route::get('/api/flights/{id}', function ($id) {
return App\Flight::findOrFail($id);
});
你可以像数组一样遍历集合:
$count = App\Flight::where('active', 1)->count();
$max = App\Flight::where('active', 1)->max('price');
分块结果
如果你需要处理数以千计的 Eloquent 结果,使用 chunk
命令。 chunk
方法会检索 Eloquent 模型中的『分块』将他们提供给指定的 Closure
处理。在处理大型结果集时,使用 chunk
方法可以节省内存:
<?php
namespace App\Http\Controllers;
use App\Flight;use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class FlightController extends Controller{
/**
* 创建一个新的航班实例
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// 校验请求...
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
}
传递到方法的第一个参数是希望每个『分块』接收的数据量。闭包作为第二个参数传递,它在每次从数据库中检索分块的时候调用。它将执行数据库查询把检索分块的结果传递给闭包方法。
使用游标
cursor
方法允许你使用游标遍历数据库,它只执行一次查询。处理大量的数据时, cursor
方法可以大大减少内存的使用量:
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';$flight->save();
检索单个模型 / 集合
除了从指定的数据表检索所有记录外,你可以使用 find
或 first
方法来检索单条记录。这些方法返回单个模型实例,而不是返回模型集合:
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
你也可以使用主键数组作为参数调用 find
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 可以被批量赋值的属性。
*
* @var array
*/
protected $fillable = ['name'];
}
{tip} Eloquent 모델도 쿼리이기 때문입니다 생성자 생성자이므로 쿼리 빌더에서 사용할 수 있는 모든 메서드에 대해서도 읽어야 합니다. Eloquent 쿼리에서 이러한 메소드를 사용할 수 있습니다. 🎜모델 다시 로드🎜🎜 fresh
및 refresh
메서드를 사용하여 다시 로드할 수 있습니다. 모델. fresh
메소드는 데이터베이스에서 모델을 다시 검색합니다. 기존 모델 인스턴스는 영향을 받지 않습니다. 🎜$flight = App\Flight::create(['name' => 'Flight 10']);
🎜 refresh
메서드는 데이터베이스의 새 데이터로 기존 모델을 다시 할당합니다. 또한 이미 로드된 관계가 다시 로드됩니다. 🎜$flight->fill(['name' => 'Flight 22']);
🎜🎜🎜컬렉션
🎜 Eloquent의 all
및 get
메소드는 여러 결과를 쿼리하고 IlluminateDatabaseEloquentCollection
인스턴스를 반환할 수 있습니다. Collection
클래스는 Eloquent 결과를 처리하기 위한 다양한 도우미 함수를 제공합니다: 🎜<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 不可批量赋值的属性。
*
* @var array
*/
protected $guarded = ['price'];
}
🎜배열처럼 컬렉션을 반복할 수 있습니다: 🎜/**
* 不可以批量赋值的属性。
*
* @var array
*/
protected $guarded = [];
🎜🎜🎜청크 결과
🎜수천 개의 Eloquent 결과를 처리해야 하는 경우 chunk
명령을 사용하세요. chunk
메소드는 Eloquent 모델의 "청크"를 검색하고 처리를 위해 지정된 Closure
에 제공합니다. 대규모 결과 세트를 처리할 때 chunk
메소드를 사용하여 메모리를 절약하세요. 🎜// 通过 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]);
🎜 메소드에 전달된 첫 번째 매개변수는 각 "청크"가 수신할 데이터의 양입니다. 클로저는 두 번째 매개변수로 전달되며 데이터베이스에서 청크가 검색될 때마다 호출됩니다. 데이터베이스 쿼리를 실행하고 검색된 청크 결과를 클로저 메소드에 전달합니다. 🎜🎜🎜커서 사용🎜🎜cursor
메서드를 사용하면 쿼리만 수행하는 커서를 사용하여 데이터베이스를 탐색할 수 있습니다. 많은 양의 데이터를 처리할 때 cursor
메서드를 사용하면 메모리 사용량을 크게 줄일 수 있습니다. 🎜// 如果有从奥克兰到圣地亚哥的航班,则价格定为99美元。
// 如果没匹配到存在的模型,则创建一个。
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);
🎜🎜🎜단일 모델/컬렉션 검색
🎜지정된 데이터 테이블에서 모든 레코드를 검색하는 것 외에도 find
또는 를 사용할 수 있습니다. 첫 번째< /code> 메소드를 사용하여 단일 레코드를 검색합니다. 이러한 메서드는 모델 컬렉션 대신 단일 모델 인스턴스를 반환합니다. 🎜$flight = App\Flight::find(1);
$flight->delete();
🎜 기본 키 배열을 인수로 사용하여 find
메서드를 호출할 수도 있습니다. 그러면 일치하는 레코드 컬렉션이 반환됩니다. 🎜 으르르르르르🎜🎜 『Not Found』Exception
모델을 찾을 수 없을 때 예외를 발생시키고 싶을 때가 있습니다. 이는 컨트롤러와 라우팅에 매우 유용합니다. findOrFail
및 firstOrFail
메소드는 쿼리의 첫 번째 결과를 검색합니다. 찾을 수 없는 경우 IlluminateDatabaseEloquentModelNotFoundException
이 발생합니다. 예외: findOrFail
和 firstOrFail
方法会检索查询的第一个结果,如果未找到,将抛出 IlluminateDatabaseEloquentModelNotFoundException
异常:
App\Flight::destroy(1);
App\Flight::destroy(1, 2, 3);
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(collect([1, 2, 3]));
如果没有捕获异常,则会自动返回 404
响应给用户。也就是说,使用这些方法时,没有必要再写个检查来返回 404
响应::
$deletedRows = App\Flight::where('active', 0)->delete();
检索集合
你还可以使用 查询构造器 提供的 count
, sum
, max
, 和其他的聚合函数。这些方法只会返回适当的标量值而不是一个模型实例:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model{
use SoftDeletes;
}
插入 & 更新模型
插入
要往数据库新增一条记录,先创建新模型实例,给实例设置属性,然后调用 save
方法:
Schema::table('flights', function (Blueprint $table)
{
$table->softDeletes();
});
在这个示例中,我们将 HTTP 请求参数 name
赋值给了 AppFlight
模型实例的 name
属性。当调用 save
方法时,将会插入一条新记录。 created_at
和 updated_at
时间戳将会自动设置,不需要手动赋值。
更新
save
方法也可以用来更新数据库已经存在的模型。更新模型,你需要先检索出来,设置要更新的属性,然后调用 save
方法。同样, updated_at
时间戳会自动更新,所以也不需要手动赋值:
if ($flight->trashed()) {
//
}
批量更新
也可以更新匹配查询条件的多个模型。在这个示例中,所有的 active
和 destination
为 San Diego
的航班会标记为延误:
$flights = App\Flight::withTrashed()
->where('account_id', 1)
->get();
update
方法接受一个键为字段名称数据为值的数组。
{note} 通过 Eloquent 批量更新时, 更新的模型不会触发 saved
和 updated
$flight->history()->withTrashed()->get();
예외가 발생하지 않으면 404
응답이 자동으로 사용자에게 반환됩니다. 즉, 이러한 메서드를 사용할 때 404
응답을 반환하기 위해 검사를 작성할 필요가 없습니다: :
$flights = App\Flight::onlyTrashed()
->where('airline_id', 1)
->get();
컬렉션 검색
제공된 count
, sum
, max를 사용할 수도 있습니다. 쿼리 빌더
및 기타 집계 함수를 사용합니다. 이러한 메서드는 모델 인스턴스가 아닌 적절한 스칼라 값을 반환합니다. $flight->restore();
🎜🎜🎜 🎜 모델 삽입 및 업데이트
🎜🎜🎜🎜삽입
🎜다음으로 이동 데이터베이스에 새 레코드를 추가하고 먼저 새 모델 인스턴스를 생성하고 인스턴스의 속성을 설정한 다음 save
메서드를 호출합니다. 🎜App\Flight::withTrashed()
->where('airline_id', 1)
->restore();
🎜이 예에서는 HTTP 요청 매개변수 name
AppFlight
모델 인스턴스의 name
속성에 할당됩니다. save
메소드가 호출되면 새 레코드가 삽입됩니다. created_at
및 updated_at
타임스탬프는 자동으로 설정되며 수동 할당이 필요하지 않습니다. 🎜🎜🎜🎜🎜update
🎜save
방법도 사용할 수 있습니다 데이터베이스에 이미 존재하는 모델을 업데이트합니다. 모델을 업데이트하려면 먼저 모델을 검색하고 업데이트할 속성을 설정한 다음 save
메서드를 호출해야 합니다. 마찬가지로 updated_at
타임스탬프는 자동으로 업데이트되므로 값을 수동으로 할당할 필요가 없습니다. 🎜$flight->history()->restore();
🎜🎜Batch update🎜 🎜쿼리 조건에 대한 여러 모델 일치 항목을 업데이트할 수도 있습니다. 이 예에서 샌디에고
행 활성
및 목적지
가 있는 모든 항공편은 지연된 것으로 표시됩니다. 🎜// 单个模型实例的永久删除...
$flight->forceDelete();
// 关联模型的永久删除...
$flight->history()->forceDelete();
🎜update
메소드는 키가 필드 이름이고 데이터가 값인 배열을 허용합니다. 🎜🎜{note} Eloquent를 통해 일괄 업데이트할 때 업데이트된 모델은 saved
및 updated
이벤트를 트리거하지 않습니다. 일괄 업데이트 중에는 모델이 검색되지 않기 때문입니다. 🎜🎜🎜🎜🎜🎜🎜🎜일괄 할당
create
메소드를 사용하여 새 모델을 저장할 수도 있습니다. 이 메소드는 모델 인스턴스를 반환합니다. 그러나 이를 사용하기 전에 모델에 fillable
또는 guarded
속성을 지정해야 합니다. 왜냐하면 모든 Eloquent 모델은 기본적으로 일괄 할당될 수 없기 때문입니다. create
方法来保存新模型,此方法会返回模型实例。不过,在使用之前,你需要在模型上指定 fillable
或 guarded
属性,因为所有的 Eloquent 模型都默认不可进行批量赋值。
当用户通过 HTTP 请求传入一个意外的参数,并且该参数更改了数据库中你不需要更改的字段时。比如:恶意用户可能会通过 HTTP 请求传入 is_admin
参数,然后将其传给 create
方法,此操作能让用户将自己升级成管理员。
所以,在开始之前,你应该定义好模型上的哪些属性是可以被批量赋值的。你可以通过模型上的 $fillable
属性来实现。 例如:让 Flight
模型的 name
属性可以被批量赋值:
<?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)
{
$builder->where('age', '>', 200);
}
}
一旦我们设置好了可以批量赋值的属性,就可以通过 create
方法插入新数据到数据库中了。 create
方法将返回保存的模型实例:
<?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);
}
}
如果你已经有一个模型实例,你可以传递一个数组给 fill
方法来赋值:
select * from `users` where `age` > 200
保护属性
$fillable
可以看作批量赋值的「白名单」, 你也可以使用 $guarded
属性来实现。 $guarded
属性包含的是不允许批量赋值的数组。也就是说, $guarded
从功能上将更像是一个「黑名单」。注意:你只能使用 $fillable
或 $guarded
二者中的一个,不可同时使用。下面这个例子中,除了 price
属性,其他的属性都可以批量赋值:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class User extends Model{
/**
*模型的「启动」方法.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope('age', function (Builder $builder) {
$builder->where('age', '>', 200);
});
}
}
如果你想让所有属性都可以批量赋值, 你可以将 $guarded
定义成一个空数组:
User::withoutGlobalScope(AgeScope::class)->get();
其他创建方法
firstOrCreate
/ firstOrNew
这里有两个你可能用来批量赋值的方法: firstOrCreate
和 firstOrNew
。firstOrCreate
方法会通过给定的 列 / 值 来匹配数据库中的数据。如果在数据库中找不到对应的模型, 则会从第一个参数的属性乃至第二个参数的属性中创建一条记录插入到数据库。
firstOrNew
方法像 firstOrCreate
方法一样尝试通过给定的属性查找数据库中的记录。不同的是,如果 firstOrNew
方法找不到对应的模型,会返回一个新的模型实例。注意 firstOrNew
返回的模型实例尚未保存到数据库中,你需要手动调用 save
사용자가 HTTP 요청을 통해 예상치 못한 매개변수를 전달하고 해당 매개변수가 변경할 필요가 없는 데이터베이스의 필드를 변경하는 경우입니다. 예를 들어, 악의적인 사용자가 HTTP 요청을 통해 is_admin
매개변수를 전달한 다음 이를 create
메소드에 전달할 수 있습니다. 이 작업을 통해 사용자는 자신을 관리자. 따라서 시작하기 전에 모델에서 일괄 할당할 수 있는 속성을 정의해야 합니다. 모델의 $fillable
속성을 통해 이 작업을 수행할 수 있습니다. 예: Flight
모델의 name
속성을 일괄 할당합니다. 🎜User::withoutGlobalScope('age')->get();
🎜 일괄 할당할 수 있는 속성을 설정한 후에는 다음을 전달할 수 있습니다. create code> 메소드는 데이터베이스에 새 데이터를 삽입합니다. create
메소드는 저장된 모델 인스턴스를 반환합니다: 🎜// 取消所有的全局作用域...
User::withoutGlobalScopes()->get();
// 取消部分全局作用域...
User::withoutGlobalScopes([
FirstScope::class, SecondScope::class
])->get();
🎜모델 인스턴스가 이미 있는 경우 배열을 fill
메소드에 전달하여 값을 할당할 수 있습니다: 🎜<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 只查询受欢迎的用户的作用域.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
/**
* 只查询 active 用户的作用域.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeActive($query)
{
return $query->where('active', 1);
}
}
🎜보호된 속성
🎜$fillable
은 일괄 할당을 위한 "허용 목록"으로 간주될 수 있습니다. 이를 달성하려면 $guarded
속성을 사용하세요. $guarded
속성에 일괄 할당을 허용하지 않는 배열이 포함되어 있습니다. 즉, $guarded
는 "블랙리스트"처럼 작동합니다. 참고: $fillable
또는 $guarded
중 하나만 사용할 수 있으며 동시에 둘 다 사용할 수는 없습니다. 다음 예에서는 price
속성을 제외하고 다른 모든 속성에 일괄적으로 값을 할당할 수 있습니다. 🎜$users = App\User::popular()->active()->orderBy('created_at')->get();
🎜 모든 속성에 값을 할당하려는 경우 일괄적으로 $guarded
가 빈 배열로 정의되도록 변경할 수 있습니다: 🎜$users = App\User::popular()->orWhere(function (Builder $query) {
$query->active();
})->get();
🎜🎜🎜🎜 기타 생성 방법🎜🎜firstOrCreate
/ firstOrNew
🎜다음은 일괄 할당에 가능한 두 가지 방법입니다: firstOrCreate
및 firstOrNew
. firstOrCreate
메서드는 데이터베이스의 데이터를 지정된 열/값과 일치시킵니다. 데이터베이스에서 해당 모델을 찾을 수 없는 경우 첫 번째 매개변수의 속성과 두 번째 매개변수의 속성까지 레코드가 생성되어 데이터베이스에 삽입됩니다. 🎜🎜firstOrNew
메서드는 firstOrCreate
메서드와 마찬가지로 주어진 속성으로 데이터베이스에서 레코드를 찾으려고 시도합니다. 차이점은 firstOrNew
메소드가 해당 모델을 찾을 수 없는 경우 새 모델 인스턴스를 반환한다는 것입니다. firstOrNew
에 의해 반환된 모델 인스턴스는 데이터베이스에 저장되지 않았습니다. 저장하려면 save
메서드를 수동으로 호출해야 합니다. 🎜$users = App\User::popular()->orWhere->active()->get();
🎜🎜updateOrCreate
updateOrCreate
你还可能遇到希望更新现有模型或在不存在的情况下则创建新的模型的情景。 Laravel 提供了 updateOrCreate
方法仅一个步骤就可以实现。跟 firstOrCreate
方法一样,updateOrCreate
匹配到对应模型,所以不需要调用 save()
方法:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 将查询作用域限制为仅包含给定类型的用户。
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param mixed $type
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
}
删除模型
可以在模型实例上调用 delete
方法来删除实例:
$users = App\User::ofType('admin')->get();
通过主键删除模型
在上面的例子中,在调用 delete
之前需要先去数据库中查找对应的模型。事实上,如果你知道了模型的主键,你可以直接使用 destroy
方法来删除模型,而不用先去数据库中查找。 destroy
方法除了接受单个主键作为参数之外,还接受多个主键,或者使用数组,集合来保存多个主键:
if ($post->is($anotherPost)) {
//
}
通过查询删除模型
你也可以在模型上运行删除语句。在这个例子中,我们将删除所有标记为非活跃的航班。与批量更新一样,批量删除不会为删除的模型启动任何模型事件:
<?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,
'deleted' => UserDeleted::class,
];
}
{note} 通过 Eloquent 执行批量删除语句时,不会触发 deleting
和 deleted
模型事件。因此,在执行删除语句时,从不检索模型示例。
软删除
除了真实删除数据库记录, Eloquent 也可以「软删除」模型。软删除的模型并不是真的从数据库中删除了。事实上,是在模型上设置了 deleted_at
属性并将其值写入数据库。如果 deleted_at
值非空,代表这个模型已被软删除。如果要开启模型软删除功能,你需要在模型上使用 IlluminateDatabaseEloquentSoftDeletes
trait:
php artisan make:observer UserObserver --model=User
{tip} SoftDeletes
trait 会自动将 deleted_at
属性转换成 DateTime
/ Carbon
实例
当然,你需要把 deleted_at
字段添加到数据表中。 Laravel 的 数据库迁移 有创建这个字段的方法:
<?php
namespace App\Observers;
use App\User;
class UserObserver{
/**
* 处理 User 「新建」事件。
*
* @param \App\User $user
* @return void
*/
public function created(User $user)
{
//
}
/**
* 处理 User 「更新」 事件。
*
* @param \App\User $user
* @return void
*/
public function updated(User $user)
{
//
}
/**
* 处理 User 「删除」 事件。
*
* @param \App\User $user
* @return void
*/
public function deleted(User $user)
{
//
}
}
那现在,当你在模型实例上使用 delete
方法, 当前日期时间会写入 deleted_at
字段。同时,查询出来的结果也会自动排除已被软删除的记录。
你可以使用 trashed
기존 모델을 업데이트하거나 존재하지 않는 경우 새 모델을 생성하려는 상황이 발생할 수도 있습니다. Laravel은 단 한 단계로 구현할 수 있는 updateOrCreate
메소드를 제공합니다. firstOrCreate
메서드와 마찬가지로 updateOrCreate
는 해당 모델과 일치하므로 save()
메서드를 호출할 필요가 없습니다.
<?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);
}
/**
* 注册服务提供者。
*
* @return void
*/
public function register()
{
//
}
}
모델 삭제
에서 delete
메소드를 호출할 수 있습니다. 인스턴스를 삭제하려면 모델 인스턴스 :rrreee기본 키로 모델 삭제위의 예에서는 먼저 데이터베이스로 이동해야 합니다. delete
호출 에서 해당 모델을 찾습니다. 실제로 모델의 기본 키를 알고 있는 경우 먼저 데이터베이스에서 모델을 조회하지 않고도 destroy
메서드를 직접 사용하여 모델을 삭제할 수 있습니다. 단일 기본 키를 매개변수로 허용하는 것 외에도 destroy
메소드는 여러 기본 키를 허용하거나 배열 또는 컬렉션을 사용하여 여러 기본 키를 저장합니다. rrreee🎜🎜쿼리를 통해 모델 삭제🎜모델에서 삭제 문을 실행할 수도 있습니다. 이 예에서는 비활성으로 표시된 모든 항공편을 삭제합니다. 일괄 업데이트와 마찬가지로 일괄 삭제는 삭제된 모델에 대한 모델 이벤트를 트리거하지 않습니다: 🎜rrreee🎜{note} Eloquent를 통해 일괄 삭제 문을 실행할 때 삭제
및 는 실행되지 않습니다. 삭제된
모델 이벤트가 발생했습니다. 따라서 삭제 문을 실행할 때 모델 예제가 검색되지 않습니다. 🎜
🎜🎜🎜🎜🎜Soft 삭제🎜🎜Eloquent는 실제로 데이터베이스 레코드를 삭제하는 것 외에도 다음과 같은 작업을 수행할 수 있습니다. "소프트 삭제" 삭제" 모델입니다. 일시 삭제된 모델은 실제로 데이터베이스에서 삭제되지 않습니다. 실제로 deleted_at
속성은 모델에 설정되고 해당 값이 데이터베이스에 기록됩니다. deleted_at
값이 비어 있지 않으면 모델이 일시 삭제되었음을 의미합니다. 모델 소프트 삭제 기능을 활성화하려면 모델에서 IlluminateDatabaseEloquentSoftDeletes
특성을 사용해야 합니다. 🎜rrreee🎜{tip} SoftDeletes
특성은 자동으로 deleted_at< /code> 속성을 삭제하면 DateTime
/ Carbon
인스턴스🎜
🎜로 변환됩니다. 물론 를 추가해야 합니다. delete_at
필드를 데이터 테이블에 추가하세요. Laravel의 데이터베이스 마이그레이션에는 이 필드를 생성하는 방법이 있습니다: 🎜rrreee🎜이제 모델 인스턴스에서 delete
메소드를 사용하면 현재 날짜와 시간이 deleted_at
에 기록됩니다. 코드> 필드. 동시에 쿼리 결과는 일시 삭제된 레코드를 자동으로 제외합니다. 🎜🎜trashed
메서드를 사용하여 현재 모델이 일시 삭제되었는지 확인할 수 있습니다. 🎜rrreee🎜🎜🎜🎜🎜🎜🎜일시 삭제된 모델 쿼리🎜🎜🎜일시 삭제된 모델 포함
앞서 언급했듯이 쿼리 결과는 일시 삭제된 결과를 자동으로 제외합니다. 물론 withTrashed
메소드를 사용하여 일시 삭제된 모델을 포함한 모델을 가져올 수 있습니다: withTrashed
方法来获取包括软删除模型在内的模型:
rrreeewithTrashed
方法也可以用在 关联 查询:
rrreee检索软删除模型
onlyTrashed
方法 只 获取已软删除的模型:
rrreee恢复软删除模型
有时会对软删除模型进行 「撤销」,在已软删除的数据上使用 restore
方法即可恢复到有效状态:
rrreee你也可以在查询中使用 restore
方法,从而快速恢复多个模型。和其他批量」操作一样,这个操作不会触发模型的任何事件:
rrreee类似 withTrashed
方法, restore
方法也用在 关联上:
rrreee永久删除
要真实删除数据时,使用 forceDelete
方法即可:
rrreee查询作用域
全局作用域
全局作用域可以给模型的查询都添加上约束。Laravel 的 软删除 功能就是利用此特性从数据库中获取 「未删除」的模型。 你可以编写你自己的全局作用域,很简单、方便的为每个模型查询都加上约束条件:
编写全局作用域
编写全局作用域很简单。定义一个实现 IlluminateDatabaseEloquentScope
接口的类,并实现 apply
这个方法。 根据你的需求,在 apply
方法中加入查询的 where
条件:
rrreee{tip} 如果需要在 select 语句里添加字段,应使用 addSelect
方法,而不是 select
方法。 这将有效防止无意中替换现有 select 语句的情况。
应用全局作用域
要将全局作用域分配给模型,需要重写模型的 boot
方法并使用 addGlobalScope
方法:
rrreee添加作用域后,对 User::all()
rrreee
withTrashed
이 메소드는 관련 쿼리에도 사용할 수 있습니다: rrreee일시 삭제된 모델 검색
onlyTrashed
메서드 만 일시 삭제된 모델 가져오기:
rrreee일시 삭제된 모델 복원🎜🎜때때로 일시 삭제된 모델이 "실행 취소"되고 일시 삭제된 데이터에 대해 restore
메서드를 사용하여 다음을 수행할 수 있습니다. 유효한 상태로 복원: 🎜rrreee🎜쿼리에서 restore
메서드를 사용하여 여러 모델을 빠르게 복원할 수도 있습니다. 다른 일괄 작업과 마찬가지로 이 작업은 모델의 어떤 이벤트도 트리거하지 않습니다. 🎜rrreee🎜 withTrashed
메서드와 유사하며 restore
메서드도 연결에 사용됩니다. 🎜rrreee 🎜🎜영구 삭제🎜🎜데이터를 실제로 삭제하려면 forceDelete
메소드를 사용하세요: 🎜rrreee🎜🎜🎜쿼리 범위
🎜🎜🎜전역 범위
🎜전역 범위는 모델 쿼리에 제약 조건을 추가할 수 있습니다. Laravel의 소프트 삭제 기능은 이 기능을 사용하여 데이터베이스에서 "삭제되지 않은" 모델을 얻습니다. 자신만의 전역 범위를 작성하고 매우 간단하고 편리하게 각 모델 쿼리에 제약 조건을 추가할 수 있습니다. 🎜🎜🎜전역 범위 작성🎜🎜 전역 범위를 작성하는 것은 쉽습니다. IlluminateDatabaseEloquentScope
인터페이스를 구현하는 클래스를 정의하고 apply
메서드를 구현합니다. 필요에 따라 apply
메소드에 쿼리의 where
조건을 추가하세요. 🎜rrreee🎜{tip} select 문에 필드를 추가해야 하는 경우 , select
메서드가 아닌 addSelect
메서드를 사용해야 합니다. 이렇게 하면 기존 select 문이 실수로 교체되는 것을 효과적으로 방지할 수 있습니다. 🎜
🎜🎜전역 범위 적용🎜🎜모델에 전역 범위를 할당하려면 모델의 부팅
을 재정의해야 합니다. 메서드를 사용하고 addGlobalScope
메서드를 사용하세요. 🎜rrreee🎜범위를 추가한 후 User::all()
에 대한 쿼리는 다음 SQL 쿼리 문을 생성합니다. 🎜rrreee🎜🎜 🎜익명 전역 범위 🎜🎜Eloquent를 사용하면 클로저를 사용하여 전역 범위를 정의할 수 있으므로 간단한 범위에 대해 별도의 클래스를 작성할 필요가 없습니다. 🎜rrreee🎜🎜전역 범위 취소
현재 쿼리의 전역 범위를 취소해야 하는 경우 withoutGlobalScope
메서드를 사용해야 합니다. 이 메소드는 전역 범위 클래스 이름만 유일한 매개변수로 허용합니다: withoutGlobalScope
方法。 该方法仅接受全局作用域类名作为它唯一的参数:
rrreee或者,如果使用闭包定义全局作用域的话:
rrreee如果你需要取消部分或者全部的全局作用域的话,需要使用 withoutGlobalScopes
方法:
rrreee本地作用域
本地作用域允许定义通用的约束集合以便在应用程序中重复使用。例如,你可能经常需要获取所有 「流行」的用户。 要定义这样一个范围,只需要在对应的 Eloquent 模型方法前添加 scope
前缀:
作用域总是返回一个查询构造器实例:
rrreee使用本地作用域
一旦定义了作用域,就可以在查询该模型时调用作用域方法。不过,在调用这些方法时不必包含 scope
前缀。甚至可以链式调用多个作用域,例如:
rrreee借助 or
查询运行符整合多个 Eloquent 模型,可能需要使用闭包回调:
rrreee因为这样可能会有点麻烦,Laravel 提供了「高阶的」 orWhere
方法,它允许你在链式调用作用域时不使用闭包:
rrreee动态作用域
有时可能地希望定义一个可以接受参数的作用域。把额外参数传递给作用域就可以达到此目的。作用域参数要放在 $query
参数之后:
rrreee这样就可以在调用作用域时传递参数了:
rrreee模型比较
有时可能需要判断两个模型是否「相同」。 is
rrreee
또는 클로저가 전역 범위를 정의하는 데 사용되는 경우: rrreee 전역 범위의 일부 또는 전체를 취소해야 하는 경우 다음을 사용해야 합니다. withoutGlobalScopes
메서드: rrreee
🎜로컬 범위
🎜 로컬 범위를 사용하면 애플리케이션 전체에서 재사용할 수 있는 공통 제약 조건 세트를 정의할 수 있습니다. 예를 들어, "인기 있는" 사용자를 모두 가져와야 하는 경우가 종종 있습니다. 이러한 범위를 정의하려면 해당 Eloquent 모델 메서드 앞에 scope
접두사를 추가하면 됩니다. 🎜🎜Scope는 항상 쿼리 빌더 인스턴스를 반환합니다: 🎜rrreee🎜🎜로컬 범위 사용🎜🎜범위가 정의되면 해당 모델을 쿼리할 때 범위 메서드를 호출할 수 있습니다. 그러나 이러한 메서드를 호출할 때 scope
접두사를 포함할 필요는 없습니다. 여러 범위에 대한 호출을 연결할 수도 있습니다. 예: 🎜rrreee🎜 여러 Eloquent 모델을 통합하려면 또는
쿼리 실행기를 사용하세요. 클로저 콜백을 사용해야 할 수도 있습니다. 🎜rrreee🎜 약간의 시간이 걸릴 수 있기 때문입니다. 번거로운 일이지만, Laravel은 클로저를 사용하지 않고 호출 범위를 연결할 수 있는 "고차" orWhere
메서드를 제공합니다: 🎜rrreee 🎜🎜 동적 범위🎜🎜 때로는 매개변수를 허용하는 범위를 정의하고 싶을 수도 있습니다. 이는 추가 매개변수를 범위에 전달하여 달성할 수 있습니다. 범위 매개변수는 $query
매개변수 뒤에 배치되어야 합니다: 🎜rrreee🎜 이렇게 하면 범위를 호출할 때 매개변수를 전달할 수 있습니다: 🎜rrreee🎜🎜🎜🎜모델 비교
🎜때로는 두 모델이 "동일"한지 확인해야 할 수도 있습니다. is
메소드를 사용하면 두 모델이 동일한 기본 키, 테이블 및 데이터베이스 연결을 가지고 있는지 빠르게 확인할 수 있습니다. 🎜rrreee🎜🎜🎜🎜🎜🎜Events
Eloquent 모델은 여러 이벤트를 트리거하여 모델 수명 주기의 다음 노드에 연결할 수 있도록 합니다: 검색됨
, 생성
, 생성됨
, 업데이트 중
, 업데이트됨
, 저장 중
, 저장됨
, 삭제 중
, 삭제됨< /code>, 복원
및 복원
. 이벤트를 사용하면 특정 모델이 데이터베이스에 저장되거나 업데이트될 때마다 코드를 실행할 수 있습니다. 각 이벤트는 생성자를 통해 모델 인스턴스를 허용합니다. retrieved
、 creating
、 created
、 updating
、 updated
、 saving
、 saved
、 deleting
、 deleted
、 restoring
和 restored
。事件允许你每当特定模型保存或更新数据库时执行代码。每个事件通过其构造器接受模型实例。
retrieved
事件在现有模型从数据库中查找数据时触发。当新模型每一次保存时, creating
和 created
事件被触发。如果数据库中已经存在模型并且调用了 save
方法, updating
/ updated
事件被触发。这些情况下, saving
/ saved
事件也被触发。
{note} 通过 Eloquent 进行批量更新时,被更新模型的 saved
和 updated
事件不会被触发。这是因为批量更新时,并没有真的获取模型。
首先,在 Eloquent 模型上定义一个 $dispatchesEvents
属性,将 Eloquent 模型生命周期的几个节点映射到你自己的 event 类 :
rrreee定义并且映射了 Eloquent 事件,就可以使用 event 监听器 listeners 处理这些事件了。
观察者
定义观察者
如果在一个模型上监听了多个事件,可以使用观察者来将这些监听器组织到一个单独的类中。观察者类的方法名映射到你希望监听的 Eloquent 事件。 这些方法都以模型作为其唯一参数。 make:observer
Artisan 命令可以快速建立新的观察者类:
rrreee此命令将在 App/Observers
文件夹放置新的观察者类。如果这个目录不存在,Artisan 将替你创建。使用如下方式开启观察者:
rrreee在你希望观察的模型上使用 observe
方法注册观察者。也可以在服务提供者的 boot
方法注册观察者。下面是在 AppServiceProvider
retrieved
이벤트는 기존 모델이 데이터베이스에서 데이터를 조회할 때 트리거됩니다. 새 모델이 저장될 때마다 creating
및 created
이벤트가 시작됩니다. 모델이 데이터베이스에 이미 존재하고 save
메소드가 호출되면 updating
/ updated
이벤트가 트리거됩니다. 이러한 경우 saving
/ saved
이벤트도 트리거됩니다. 먼저 Eloquent 모델 수명 주기의 여러 노드를 자신의 이벤트 클래스에 매핑하기 위해 Eloquent 모델에 $dispatchesEvents
속성을 정의합니다. rrreee🎜 Eloquent 이벤트를 정의하고 매핑합니다. 이벤트 리스너를 사용하여 이러한 이벤트를 처리할 수 있습니다. 🎜🎜🎜🎜🎜관찰자
🎜관찰자 정의
🎜모델에서 여러 이벤트를 수신하는 경우 관찰자를 사용하여 이러한 청취자를 별도의 클래스로 구성할 수 있습니다. 관찰자 클래스의 메소드 이름은 듣고자 하는 Eloquent 이벤트에 매핑됩니다. 이러한 방법은 모두 모델을 유일한 매개변수로 사용합니다. make:observer
Artisan 명령은 새로운 관찰자 클래스를 빠르게 생성할 수 있습니다: 🎜rrreee🎜 이 명령은 App/Observers
폴더에 새로운 관찰자 클래스를 배치합니다. 이 디렉토리가 존재하지 않으면 Artisan이 이를 생성합니다. 관찰자를 활성화하려면 다음 방법을 사용하세요. 🎜rrreee🎜 관찰하려는 모델에 관찰자를 등록하려면 observe
메서드를 사용하세요. 관찰자는 서비스 제공자의 boot
메소드에 등록할 수도 있습니다. 다음은 AppServiceProvider
에 관찰자를 등록하는 예입니다. 🎜rrreee🎜이 기사는 🎜LearnKu.com🎜 웹사이트에 처음 게재되었습니다. 🎜🎜모델 협회 →