2020 年更新
就像在 Laravel >= 5.3 中一样,如果有人仍然想知道如何以简单的方式做到这一点,可以使用:updateOrCreate()。
例如,对于提出的问题,您可以使用以下内容:
$matchThese = ['shopId'=>$theID,'metadataKey'=>2001];
ShopMeta::updateOrCreate($matchThese,['shopOwner'=>'New One']);
上面的代码将检查 ShopMeta 表示的表,除非模型本身没有另外定义,否则很可能是 shop_metas。
它会尝试找到条目
列shopId = $theID
和
列metadateKey = 2001
如果找到,则将找到的行的列 shopOwner 更新为 New One。
如果它找到多个匹配行,那么它将更新第一行,这意味着具有最低主id。
如果根本没有找到,那么它将插入一个新行:
shopId = $theID,metadateKey = 2001 和 shopOwner = New One
通知
检查您的模型中的 $fillable 并确保您在其中定义了要插入或更新的每个列名,并且其余列具有默认值或其 id 列自动递增一个。
否则执行上面的例子会报错:
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field '...' doesn't have a default value (SQL: insert into `...` (`...`,.., `updated_at`, `created_at`) values (...,.., xxxx-xx-xx xx:xx:xx, xxxx-xx-xx xx:xx:xx))'
因为在插入新行时会有一些需要值的字段,这是不可能的,因为它没有在$fillable 中定义,或者它没有默认值。
如需更多参考,请参阅 Laravel 文档:
https://laravel.com/docs/5.3/eloquent
一个例子是:
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);
这几乎可以清除所有内容。
查询生成器更新
有人问是否可以在 Laravel 中使用查询生成器。 Here 是 Laravel 文档中查询生成器的参考。
Query Builder 的工作方式与 Eloquent 完全相同,因此任何适用于 Eloquent 的内容也适用于 Query Builder。因此,对于这种特定情况,只需在查询构建器中使用相同的函数,如下所示:
$matchThese = array('shopId'=>$theID,'metadataKey'=>2001);
DB::table('shop_metas')::updateOrCreate($matchThese,['shopOwner'=>'New One']);
当然,别忘了加上DB门面:
use Illuminate\Support\Facades\DB;
或
use DB;