多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 插入与更新 ### [](https://octobercms.com/docs/database/model#inserting-and-updating-models)插入和更新模型 插入和更新数据是模型的基石,与传统的SQL语句相比,它使过程变得轻松。 ### [](https://octobercms.com/docs/database/model#basic-inserts)基本插入 要在数据库中创建新记录,只需创建一个新的模型实例,在模型上设置属性,然后调用该`save`方法: ~~~ $flight = new Flight; $flight->name = 'Sydney to Canberra'; $flight->save(); ~~~ 在此示例中,我们仅创建`Flight`模型的新实例并分配`name`属性。当我们调用该`save`方法时,一条记录将被插入数据库中。在`created_at`和`updated_at`时间戳将自动设置太多,所以没有必要进行手动设置。 ### [](https://octobercms.com/docs/database/model#basic-updates)基本更新 该`save`方法还可以用于更新数据库中已经存在的模型。要更新模型,您应该检索它,设置要更新的任何属性,然后调用该`save`方法。同样,`updated_at`时间戳将自动更新,因此无需手动设置其值: ~~~ $flight = Flight::find(1); $flight->name = 'Darwin to Adelaide'; $flight->save(); ~~~ 还可以针对与给定查询匹配的任何数量的模型执行更新。在这个例子中,所有的航班`active`,有一个`destination`的`San Diego`将被标记为延迟: ~~~ Flight::where('is_active', true) ->where('destination', 'Perth') ->update(['delayed' => true]); ~~~ 该`update`方法需要一个列和值对的数组,这些数组代表应该更新的列。 #### 更新或插入/`upsert()`(批处理查询以在一个数据库调用中处理多行) 如果您想在单个查询中执行多个“ upserts”,则应改用该`upsert`方法。该方法的第一个参数由要插入或更新的值组成,而第二个参数列出了唯一标识关联表中的记录的列。该方法的第三个也是最后一个参数是列的数组,如果数据库中已经存在匹配的记录,则应更新这些列。如果在模型上启用了时间戳,则该`upsert`方法将自动设置`created_at`和`updated_at`时间戳: ~~~ MyVendor\MyPlugin\Models\Flight::upsert([ ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150] ], ['departure', 'destination'], ['price']); ~~~ > **注意::**除SQL Server以外,所有数据库均要求该`upsert`方法第二个参数中的列具有“主”或“唯一”索引。 ### [](https://octobercms.com/docs/database/model#mass-assignment)批量分配 您也可以使用该`create`方法在一行中保存新模型。插入的模型实例将从该方法返回给您。但是,在执行此操作之前,您需要在模型上指定a`fillable`或`guarded`属性,因为所有模型都可以防止大规模分配。请注意,无论是`fillable`或`guarded`影响提交后端的形式,只使用`create`或`fill`方法。 当用户通过请求传递意外的HTTP参数,并且该参数更改了数据库中您没有期望的列时,就会发生批量分配漏洞。例如,恶意用户可能`is_admin`通过HTTP请求发送参数,然后将该参数映射到模型的`create`方法上,从而使该用户可以升级为管理员。 首先,您应该定义要批量分配的模型属性。您可以使用`$fillable`模型上的属性来执行此操作。例如,让我们使模型的`name`属性`Flight`可分配: ~~~ class Flight extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name']; } ~~~ 一旦使属性可大规模分配,就可以使用该`create`方法在数据库中插入新记录。该`create`方法返回保存的模型实例: ~~~ $flight = Flight::create(['name' => 'Flight 10']); ~~~ 虽然`$fillable`它是应该批量分配的属性“白名单”,但您也可以选择使用`$guarded`。该`$guarded`属性应包含您不希望被大量分配的属性数组。不在数组中的所有其他属性将可批量分配。因此,`$guarded`功能类似于“黑名单”。当然,您应该使用`$fillable`或`$guarded`不使用以下两者之一: ~~~ class Flight extends Model { /** * The attributes that aren't mass assignable. * * @var array */ protected $guarded = ['price']; } ~~~ 在上面的示例中,**除以外的`price`**所有属性**都是**可批量分配的。 #### 其他创作方法 有时您可能只希望实例化模型的新实例。您可以使用`make`方法执行此操作。该`make`方法将简单地返回一个新实例,而不保存或创建任何东西。 ~~~ $flight = Flight::make(['name' => 'Flight 10']); // Functionally the same as... $flight = new Flight; $flight->fill(['name' => 'Flight 10']); ~~~ 通过批量分配属性,可以使用两种其他方法来创建模型:`firstOrCreate`和`firstOrNew`。该`firstOrCreate`方法将尝试使用给定的列/值对查找数据库记录。如果在数据库中找不到模型,则将插入具有给定属性的记录。 该`firstOrNew`方法`firstOrCreate`将尝试在数据库中找到与给定属性匹配的记录。但是,如果找不到模型,则将返回新的模型实例。请注意,所返回的模型`firstOrNew`尚未持久化到数据库中。您将需要`save`手动调用以保留它: ~~~ // Retrieve the flight by the attributes, otherwise create it $flight = Flight::firstOrCreate(['name' => 'Flight 10']); // Retrieve the flight by the attributes, or instantiate a new instance $flight = Flight::firstOrNew(['name' => 'Flight 10']); ~~~