{"id":22465,"date":"2024-11-21T12:15:29","date_gmt":"2024-11-21T04:15:29","guid":{"rendered":"https:\/\/fwq.ai\/blog\/22465\/"},"modified":"2024-11-21T12:15:29","modified_gmt":"2024-11-21T04:15:29","slug":"laravel-eloquent%e6%a8%a1%e5%9e%8b%e4%b8%ad%e4%b9%90%e8%a7%82%e9%94%81%e7%9a%84%e5%ae%9e%e7%8e%b0","status":"publish","type":"post","link":"https:\/\/fwq.ai\/blog\/22465\/","title":{"rendered":"Laravel Eloquent\u6a21\u578b\u4e2d\u4e50\u89c2\u9501\u7684\u5b9e\u73b0"},"content":{"rendered":"<p>\u672c\u7bc7\u6587\u7ae0\u7ed9\u5927\u5bb6\u5e26\u6765\u4e86\u5173\u4e8e\u7684\u76f8\u5173\u77e5\u8bc6\uff0c\u5176\u4e2d\u4e3b\u8981\u8ddf\u5927\u5bb6\u4ecb\u7ecdlaravel eloquent\u6a21\u578b\u4e2d\u4e50\u89c2\u9501\u7684\u5b9e\u73b0\uff0c\u6709\u4ee3\u7801\u793a\u4f8b\uff0c\u611f\u5174\u8da3\u7684\u670b\u53cb\u4e0b\u9762\u4e00\u8d77\u6765\u770b\u4e00\u4e0b\u5427\uff0c\u5e0c\u671b\u5bf9\u5927\u5bb6\u6709\u5e2e\u52a9\u3002<\/p>\n<blockquote><p>\n  \u5728app\/Utils\/Traits\u76ee\u5f55\u4e0b\u521b\u5efaOptimisticLockTrait.php\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\n<\/p><\/blockquote>\n<pre>namespace AppUtilsTraits;use IlluminateDatabaseEloquentBuilder;trait OptimisticLockTrait{\n\n    \/**\n     * @var array $optimisticConditions\n     * @var array $bindings\n     *\/\n    protected $optimisticConditions, $bindings;\n    \/**\n     * @var string $optimisticConditionRaw\n     *\/\n    protected $optimisticConditionRaw;\n\n    \/**\n     * save \u65f6\u589e\u52a0\u4e50\u89c2\u9501\u6761\u4ef6\n     * @param Builder $builder\n     *\/\n    protected function performUpdate(Builder $builder)\n    {\n        if (!empty($this-&gt;optimisticConditions)) {\n            foreach ($this-&gt;optimisticConditions as $field =&gt; $value) {\n                if (is_array($value)) {\n                    $count = count($value);\n                    if ($count &gt;= 3) {\n                        switch (strtoupper($value[1])) {\n                            case 'IN':\n                                $builder-&gt;whereIn($value[0], $value[2]);\n                                break;\n                            case 'NOT IN':\n                                $builder-&gt;whereNotIn($value[0], $value[2]);\n                                break;\n                            case 'BETWEEN':\n                                $builder-&gt;whereBetween($value[0], $value[2]);\n                                break;\n                            case 'NOT BETWEEN':\n                                $builder-&gt;whereNotBetween($value[0], $value[2]);\n                                break;\n                            default:\n                                $builder-&gt;where($value[0], $value[1], $value[2]);\n                        }\n                    } else {\n                        $builder-&gt;where($value);\n                    }\n                } else {\n                    $builder-&gt;where($field, $value);\n                }\n            }\n        }\n        \/\/ \u539f\u59cb\u6761\u4ef6\u6ce8\u5165\n        if ($this-&gt;optimisticConditionRaw)\n            $builder-&gt;whereRaw($this-&gt;optimisticConditionRaw, $this-&gt;bindings);\n\n        return $this-&gt;clearOptimistic()-&gt;perFormUpdating($builder);\n\n    }\n\n\n    \/**\n     * updating with optimistic\n     *\n     * @param Builder $builder\n     * @return bool\n     *\/\n    protected function perFormUpdating(Builder $builder)\n    {\n\n        \/\/ If the updating event returns false, we will cancel the update operation so\n        \/\/ developers can hook Validation systems into their models and cancel this\n        \/\/ operation if the model does not pass validation. Otherwise, we update.\n        if ($this-&gt;fireModelEvent('updating') === false) {\n            return false;\n        }\n\n        \/\/ First we need to create a fresh query instance and touch the creation and\n        \/\/ update timestamp on the model which are maintained by us for developer\n        \/\/ convenience. Then we will just continue saving the model instances.\n        if ($this-&gt;usesTimestamps()) {\n            $this-&gt;updateTimestamps();\n        }\n\n        \/\/ Once we have run the update operation, we will fire the \"updated\" event for\n        \/\/ this model instance. This will allow developers to hook into these after\n        \/\/ models are updated, giving them a chance to do any special processing.\n        $dirty = $this-&gt;getDirty();\n        $res = 0;\n        if (count($dirty) &gt; 0) {\n            $res = $this-&gt;setKeysForSaveQuery($builder)-&gt;update($dirty);\n\n            $this-&gt;syncChanges();\n\n            $this-&gt;fireModelEvent('updated', false);\n        }\n        return !empty($res);\n    }\n\n    \/\/ \u6e05\u9664\u4e50\u89c2\u9501\u6761\u4ef6\n    function clearOptimistic()\n    {\n        $this-&gt;optimisticConditions = null;\n        $this-&gt;optimisticConditionRaw = null;\n        return $this;\n    }\n\n\n    \/\/ \u8bbe\u7f6e\u4e50\u89c2\u9501\u6761\u4ef6\u5b57\u6bb5\u540d\u5217\u8868\n    function setOptimistic(array $optimisticConditions)\n    {\n        $this-&gt;optimisticConditions = $optimisticConditions;\n        return $this;\n    }\n\n    \/\/ \u8bbe\u7f6e\u4e50\u89c2\u9501\u539f\u59cb\u6761\u4ef6\u5b57\u6bb5\u540d\u5217\u8868\n    function setOptimisticRaw(string $optimisticConditionRaw, array $bindings = [])\n    {\n        $this-&gt;optimisticConditionRaw = $optimisticConditionRaw;\n        $this-&gt;bindings = $bindings;\n        return $this;\n    }}<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<blockquote>\n<p>\u4e50\u89c2\u9501\u4f7f\u7528\u8bf4\u660e<\/p>\n<\/blockquote>\n<p>1\u3001\u5728\u6a21\u578b\u4e2d(Models)\u6216\u6a21\u578b\u7236\u7c7b\u4f7f\u7528<\/p>\n<pre>\/**\n* AppModelsBaseModel\n* @mixin Eloquent\n* @method static IlluminateDatabaseEloquentBuilder|BaseModel newModelQuery()\n* @method static IlluminateDatabaseEloquentBuilder|BaseModel newQuery()\n* @method static IlluminateDatabaseEloquentBuilder|BaseModel query()\n*\/class BaseModel extends Model{\n  use OptimisticLockTrait;}<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<p>2\u3001\u4f7f\u7528\u65b9\u6cd5\uff1a<\/p>\n<pre> $ord = Order::find(1);\n $ord-&gt;payment_status = 1;\n if(!$model-&gt;setOptimistic(['payment_status' =&gt; 0]))-&gt;save())\n   throws new Exception('\u8ba2\u5355\u5df2\u4ed8\u8fc7\u6b3e\u4e86');<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<p>\u6216\u8005\u4f7f\u7528\u539f\u59cbSQL\u65b9\u5f0f:<\/p>\n<pre> $ord = Order::find(1);\n $ord-&gt;payment_status = 1;\n if(!$model-&gt;setOptimisticRaw('payment_status = ?',[1]))-&gt;save())\n   throws new Exception('\u8ba2\u5355\u5df2\u4ed8\u8fc7\u6b3e\u4e86');<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<p>\u5982\u679c\u540c\u4e00\u5bf9\u8c61\u5c0f\u6d89\u53ca\u5230\u591a\u6b21\u66f4\u65b0\uff0c\u5219\u53ef\u4ee5\u6e05\u9664\u9501\u6761\u4ef6<\/p>\n<pre>$ord-&gt;clearOptimistic();<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<p>\u4ee5\u4e0a\u5c31\u662f\u4e50\u89c2\u9501\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u5728\u5b9e\u9645\u5f00\u53d1\u4e2d\u6bd4\u8f83\u5e38\u7528\u4e5f\u5f88\u6709\u5fc5\u8981\u3002<\/p>\n<p>\u63a8\u8350\u5b66\u4e60\uff1a\u300a\u300b<\/p>\n<p>\u4ee5\u4e0a\u5c31\u662fLaravel Eloquent\u6a21\u578b\u4e2d\u4e50\u89c2\u9501\u7684\u5b9e\u73b0\u7684\u8be6\u7ec6\u5185\u5bb9\uff0c\u66f4\u591a\u8bf7\u5173\u6ce8\u7c73\u4e91\u5176\u5b83\u76f8\u5173\u6587\u7ae0\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u7bc7\u6587\u7ae0\u7ed9\u5927\u5bb6\u5e26\u6765\u4e86\u5173\u4e8e\u7684\u76f8\u5173\u77e5\u8bc6\uff0c\u5176\u4e2d\u4e3b\u8981\u8ddf\u5927\u5bb6\u4ecb\u7ecdlaravel eloquent\u6a21\u578b\u4e2d\u4e50\u89c2\u9501\u7684\u5b9e\u73b0\uff0c\u6709\u4ee3\u7801\u793a\u4f8b\uff0c\u611f\u5174\u8da3\u7684\u670b\u53cb\u4e0b\u9762\u4e00\u8d77\u6765\u770b\u4e00\u4e0b\u5427\uff0c\u5e0c\u671b\u5bf9\u5927\u5bb6\u6709\u5e2e\u52a9\u3002 \u5728app\/Utils\/Traits\u76ee\u5f55\u4e0b\u521b\u5efaOptimisticLockTrait.php\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a namespace AppUtilsTraits;use IlluminateDatabaseEloquentBuilder;trait OptimisticLockTrait{ \/** * @var array $optimisticConditions * @var array $bindings *\/ protected $optimisticConditions, $bindings; \/** * @var string $optimisticConditionRaw *\/ protected $optimisticConditionRaw; \/** * save \u65f6\u589e\u52a0\u4e50\u89c2\u9501\u6761\u4ef6 * @param Builder $builder *\/ protected function performUpdate(Builder $builder) { if (!empty($this-&gt;optimisticConditions)) { foreach ($this-&gt;optimisticConditions as $field =&gt; $value) { if (is_array($value)) { [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[],"class_list":["post-22465","post","type-post","status-publish","format-standard","hentry","category-16"],"_links":{"self":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/22465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/comments?post=22465"}],"version-history":[{"count":0,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/22465\/revisions"}],"wp:attachment":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/media?parent=22465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/categories?post=22465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/tags?post=22465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}