如何写一个属于自己的数据库封装(7) - UPDATE篇(修订版)

上一期 如何写一个属于自己的数据库封装(6) - 查询 - WHERE篇
下一期 如何写一个属于自己的数据库封装(8) - CREATE篇

基本思路

在开始代码之前, 我们需要回想一些日常面对的难题, 或则说不良体验

在实现业务逻辑时, 我们往往都会遇到以下类似场景

确认A先生(id=233)是否会员, 如果是, 修改字段'status'为'active', 否则删除它

在没有框架的时候一般都会这么写的(以下代码略过所有pdo逻辑)

// 首先查询A先生的数据, 获取他的身份
$a = 'select * from users where id = 233';
// 判定是否为会员
if($a->member === true)
    // 是就修改字段
   $b = 'update users set status = 'active' where id = 233';
else
   // 否就删除数据
   $b= 'delete from users where id = 233';

注意, 这是因为我们简略了pdo的所有步骤, 试想想更复杂的业务逻辑, 曾经见过满满上千行都是SQL语句的, 代码可读性等于0, 重构无能
所以,凭什么我们需要写的这么多呢, 可以简化啊!

可再操作的数据

当数据返回后,将其转化为实例, 该实例附带函数, 可以进行某些操作

这就是查询 - 入门篇中为什么数据返回后会被放入函数cast()当中进行转化的原因

使用封装后可以这么做

// 首先查询A先生的数据, 获取他的身份
$a = User::find(233);
// 判定是否存在该id和该id是否为会员
if($a & $a->member)
    // 是就修改字段
   $b = $a->update(['status'=>'active']);
else
   // 否就删除数据
   $b= $a->delete();

接下来我们需要思考

如何对数据库数据进行修改?

这是我自己的肤浅答案

常见的情况我们需要用到条件语法, 对需要修改的数据指定范围, 过滤无需改写的数据

根据以上的说明, 有三种例子
1.完全不指定范围, 修改表内所有数据

update Actor set first_name = 'new data'

2.指定范围, 修改匹配条件的多条数据

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

3.指定范围, 依据表的 identity key 或 unique key 修改指定单条数据

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

根据以上的三种类型, 我们可以开始开发update函数了,
PS:过于高级的update语句我因为经验尚浅无法理解/不曾使用, 欢迎留言


Builder.php

在最后一行添加update函数

    // 改写数据库数据
    public function update(array $values) {
        // 如果写保护已经开启,跳出错误
        if($this->writeLock) throw new Exception("data is not allow to update");

        // 编译update语句
        $sql = $this->grammar->compileUpdate($this, $values);

        // 将所有变量的值合成一个数组, 其中包括条件语句部分
        $bindings = array_values(array_merge($values, $this->getBindings()));

        // 返回改写结果,成功true失败false
        return $this->connector->update($sql, $bindings);
    }

Grammar.php

在最后一行添加compileUpdate函数

    public function compileUpdate(Builder $query, $values) {
        // 循环$values, 记得引用
        foreach ($values as $key => &$value)
            // 将所有$value改成对应的$key=?
            $value = $key.' = ?';

        // 将$values中的之全部掏出在连接起来
        $columns = implode(', ', array_values($values));

        // 附上where语句如果有
        // 由于更复杂的sql update语句我还没试过, 为了不坑人, 所以限制只有where语法有效
        // 欢迎提供更复杂的where语句
        $where = is_null($query->wheres) ? '' : $this->compileWheres($query);

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

Model.php

添加函数 save, 用法见下面例子

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

例子

  • 修改指定数据
$a = Actor::where('first_name', 'ANGELINA')
    ->update(['last_name'=>'changed']);
dd($a);
  • 再操作数据实例
$a = Actor::where('first_name', 'ANGELINA')
    ->first();
dd($a->update(['last_name'=>'again']));
  • 再操作数据实例, 另一种用法
$a = Actor::where('first_name', 'ANGELINA')
    ->first();

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

返回结果

boolean true
// 失败返回 false

完整代码

源代码放在coding.net里, 自己领

上一期 如何写一个属于自己的数据库封装(6) - 查询 - WHERE篇
下一期 如何写一个属于自己的数据库封装(8) - CREATE篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容