如何寫(xiě)一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(7) - UPDATE篇(修訂版)

上一期 如何寫(xiě)一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(6) - 查詢(xún) - WHERE篇
下一期 如何寫(xiě)一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(8) - CREATE篇

基本思路

在開(kāi)始代碼之前, 我們需要回想一些日常面對(duì)的難題, 或則說(shuō)不良體驗(yàn)

在實(shí)現(xiàn)業(yè)務(wù)邏輯時(shí), 我們往往都會(huì)遇到以下類(lèi)似場(chǎng)景

確認(rèn)A先生(id=233)是否會(huì)員, 如果是, 修改字段'status'為'active', 否則刪除它

在沒(méi)有框架的時(shí)候一般都會(huì)這么寫(xiě)的(以下代碼略過(guò)所有pdo邏輯)

// 首先查詢(xún)A先生的數(shù)據(jù), 獲取他的身份
$a = 'select * from users where id = 233';
// 判定是否為會(huì)員
if($a->member === true)
    // 是就修改字段
   $b = 'update users set status = 'active' where id = 233';
else
   // 否就刪除數(shù)據(jù)
   $b= 'delete from users where id = 233';

注意, 這是因?yàn)槲覀兒?jiǎn)略了pdo的所有步驟, 試想想更復(fù)雜的業(yè)務(wù)邏輯, 曾經(jīng)見(jiàn)過(guò)滿滿上千行都是SQL語(yǔ)句的, 代碼可讀性等于0, 重構(gòu)無(wú)能
所以,憑什么我們需要寫(xiě)的這么多呢, 可以簡(jiǎn)化啊!

可再操作的數(shù)據(jù)

當(dāng)數(shù)據(jù)返回后,將其轉(zhuǎn)化為實(shí)例, 該實(shí)例附帶函數(shù), 可以進(jìn)行某些操作

這就是查詢(xún) - 入門(mén)篇中為什么數(shù)據(jù)返回后會(huì)被放入函數(shù)cast()當(dāng)中進(jìn)行轉(zhuǎn)化的原因

使用封裝后可以這么做

// 首先查詢(xún)A先生的數(shù)據(jù), 獲取他的身份
$a = User::find(233);
// 判定是否存在該id和該id是否為會(huì)員
if($a & $a->member)
    // 是就修改字段
   $b = $a->update(['status'=>'active']);
else
   // 否就刪除數(shù)據(jù)
   $b= $a->delete();

接下來(lái)我們需要思考

如何對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行修改?

這是我自己的膚淺答案

常見(jiàn)的情況我們需要用到條件語(yǔ)法, 對(duì)需要修改的數(shù)據(jù)指定范圍, 過(guò)濾無(wú)需改寫(xiě)的數(shù)據(jù)

根據(jù)以上的說(shuō)明, 有三種例子
1.完全不指定范圍, 修改表內(nèi)所有數(shù)據(jù)

update Actor set first_name = 'new data'

2.指定范圍, 修改匹配條件的多條數(shù)據(jù)

update Actor set first_name = 'new data' where first_name like '%L%'

3.指定范圍, 依據(jù)表的 identity key 或 unique key 修改指定單條數(shù)據(jù)

update Actor set first_name = 'new data' where actor_id = 10

根據(jù)以上的三種類(lèi)型, 我們可以開(kāi)始開(kāi)發(fā)update函數(shù)了,
PS:過(guò)于高級(jí)的update語(yǔ)句我因?yàn)榻?jīng)驗(yàn)尚淺無(wú)法理解/不曾使用, 歡迎留言


Builder.php

在最后一行添加update函數(shù)

    // 改寫(xiě)數(shù)據(jù)庫(kù)數(shù)據(jù)
    public function update(array $values) {
        // 如果寫(xiě)保護(hù)已經(jīng)開(kāi)啟,跳出錯(cuò)誤
        if($this->writeLock) throw new Exception("data is not allow to update");

        // 編譯update語(yǔ)句
        $sql = $this->grammar->compileUpdate($this, $values);

        // 將所有變量的值合成一個(gè)數(shù)組, 其中包括條件語(yǔ)句部分
        $bindings = array_values(array_merge($values, $this->getBindings()));

        // 返回改寫(xiě)結(jié)果调塌,成功true失敗false
        return $this->connector->update($sql, $bindings);
    }

Grammar.php

在最后一行添加compileUpdate函數(shù)

    public function compileUpdate(Builder $query, $values) {
        // 循環(huán)$values, 記得引用
        foreach ($values as $key => &$value)
            // 將所有$value改成對(duì)應(yīng)的$key=?
            $value = $key.' = ?';

        // 將$values中的之全部掏出在連接起來(lái)
        $columns = implode(', ', array_values($values));

        // 附上where語(yǔ)句如果有
        // 由于更復(fù)雜的sql update語(yǔ)句我還沒(méi)試過(guò), 為了不坑人, 所以限制只有where語(yǔ)法有效
        // 歡迎提供更復(fù)雜的where語(yǔ)句
        $where = is_null($query->wheres) ? '' : $this->compileWheres($query);

        // 返回update語(yǔ)句
        return trim("update $query->from set $columns $where");
    }

Model.php

添加函數(shù) save, 用法見(jiàn)下面例子

    // 一種更快捷的update方式
    public function save() {
        return $this->update((array)$this->data);
    }

例子

  • 修改指定數(shù)據(jù)
$a = Actor::where('first_name', 'ANGELINA')
    ->update(['last_name'=>'changed']);
dd($a);
  • 再操作數(shù)據(jù)實(shí)例
$a = Actor::where('first_name', 'ANGELINA')
    ->first();
dd($a->update(['last_name'=>'again']));
  • 再操作數(shù)據(jù)實(shí)例, 另一種用法
$a = Actor::where('first_name', 'ANGELINA')
    ->first();

$a->last_name = 'save';
dd($a->save());

返回結(jié)果

boolean true
// 失敗返回 false

完整代碼

源代碼放在coding.net里, 自己領(lǐng)

上一期 如何寫(xiě)一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(6) - 查詢(xún) - WHERE篇
下一期 如何寫(xiě)一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(8) - CREATE篇

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壹士,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辣卒,老刑警劉巖掷贾,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異荣茫,居然都是意外死亡想帅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)啡莉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)港准,“玉大人,你說(shuō)我怎么就攤上這事咧欣∏掣祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵魄咕,是天一觀的道長(zhǎng)衩椒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)哮兰,這世上最難降的妖魔是什么毛萌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮喝滞,結(jié)果婚禮上阁将,老公的妹妹穿的比我還像新娘。我一直安慰自己右遭,他們只是感情好做盅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著窘哈,像睡著了一般吹榴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滚婉,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天腊尚,我揣著相機(jī)與錄音,去河邊找鬼满哪。 笑死婿斥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的哨鸭。 我是一名探鬼主播民宿,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼像鸡!你這毒婦竟也來(lái)了活鹰?” 一聲冷哼從身側(cè)響起哈恰,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎志群,沒(méi)想到半個(gè)月后着绷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锌云,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年荠医,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑涎。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彬向,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攻冷,到底是詐尸還是另有隱情娃胆,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布等曼,位于F島的核電站里烦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏禁谦。R本人自食惡果不足惜胁黑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枷畏。 院中可真熱鬧别厘,春花似錦虱饿、人聲如沸拥诡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)渴肉。三九已至,卻和暖如春爽冕,著一層夾襖步出監(jiān)牢的瞬間仇祭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工颈畸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乌奇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓眯娱,卻偏偏與公主長(zhǎng)得像礁苗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徙缴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容