文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

TP5 模型更新的返回值、返回值的判断以及所使用的SQL

2023-09-06 06:02

关注

TP5 模型更新主要使用静态方法 update 和动态方法 save 

静态方法 update

直接使用模型类静态调用,例如 User 模型类更新主键为1的用户的 username 为 a

方式一

$data = ['id' => 1, 'username' => 'a'];User::update($data);

把更新条件 id 写在更新的数据数组里,因为 id 为模型默认的主键名称,所以方法能自动识别
如果需要更改模型的默认主键名称,更改模型的 pk 属性值( protected $pk = )即可
这种方式只支持主键作为更新条件

方式二

$data = ['username'=>'a'];User::update($data, ['id' => '1']);

把更新条件( id = 1 )写在 update 方法的第二个参数(数组)里,如下

$data = ['username'=>'a'];User::update($data, ['id' => '1']);

这种方式支持非主键字段作为更新条件,并且支持多个更新条件

例如把 username 等于 a 并且 status 等于 1 的 username 修改为 aa,如下

$data = ['username'=>'aa'];User::update($data, ['username' => 'a','status'=> 1]);

温馨提示

把方式一和方式二混写是不行的,如下

$data = ['id' => 1, 'username' => 'a'];User::update($data, ['status' => 1]);

本意是想把主键 id 等于1 而且 status 等于 1 的这行的 username 字段的字段值改为 a,如果把主键 id 写在 update 方法的第一个参数,status 写在 update 方法第二个参数(如上),生成的 SQL 如下

 UPDATE `user` SET `username` = 'a' WHERE `id` = 1

只用上主键 id,没有用到 status,显然是错误的。

返回值

和 Db 类的 update 方法的返回值不同,Db 类的 update 方法返回的是影响行数,而模型的 update 方法返回的是更新数据的模型类的实例

举例

把 id 等于 1 的 username 修改为 aa

$data = ['id' => 1, 'username' => 'aa'];$result = User::update($data);echo ("
");var_dump($result);echo ("
");

返回的是更新数据的 User 类实例(当前更新数据有 id =1和 username = aa) ,更新数据保存在 User 类实例的 data 属性(数组)里,如下

object(app\index\model\User)#43 (2) {  ["data"]=>  array(3) {    ["id"]=>    int(1)    ["username"]=>    string(1) "aa"  }  ["relation"]=>  array(0) {  }}

生成的 SQL 语句如下

UPDATE `user` SET `username` = 'aa' WHERE `id` = 1 

重要提醒

模型的 update 方法只管执行 SQL 不管 SQL 执行后的结果,执行 SQL 成功则返回当前更新数据的模型类实例,执行 SQL 失败则抛出异常,所以无需判断 update 方法的返回值。

模型的 update 方法无论更新条件的字段值是否存在都可以执行更新并返回更新数据的模型类实例而且不会有任何错误提示,所以更新前要先确保更新条件的字段值存在。

举例

把 id 等于 111 的 username 修改为 aa(id 等于 111 的用户在数据库内是不存在的),代码如下

$data = ['id' => 111, 'username' => 'aa'];$result = User::update($data);echo ("
");var_dump($result);echo ("
");

返回

object(app\index\model\User)#43 (2) {  ["data"]=>  array(3) {    ["id"]=>    int(111)    ["username"]=>    string(2) "aa"  }  ["relation"]=>  array(0) {  }}

id 等于 111 的用户在数据库内是不存在的,但方法依旧能执行,并返回更新数据的模型类的实例,执行的 SQL 如下

UPDATE `user` SET `username` = 'aa' WHERE `id` = 111

执行 update 方法成功不代表更新数据成功,如果当前更新数据的字段名在数据库内是不存在的, update 方法是不会向数据库发送 SQL 语句的,测试如下

$data = ['name' => 'a']; // name 字段在表结构中是不存在的$result = User::update($data, ['id' => 1]);

因为模型在执行更新操作前,会发送一条 SQL 语句获得表结构,如下

 SHOW COLUMNS FROM `user`

因为 name 字段在表结构中是不存在的,所以 update 方法是不会向数据库发送 SQL 语句的,而且 update 方法不会有任何错误提示,依然能返回更新数据的模型类实例,如下

object(app\index\model\User)#43 (2) {  ["data"]=>  array(1) {    ["name"]=>    string(1) "a"  }  ["relation"]=>  array(0) {  }}

动态方法 save

实例化模型类后动态调用,例如 User 对象更新主键为1的用户的 username 为 a

$user = new User();$data = ['username' => 'a'];$where = ['id' => 1];$result = $user->save($data, $where);

save 方法的使用方式分两种情况

1、先查询出数据后再进行更新

$user = User::get(1);//取得主键为1的 User 类实例$data = ['username' => 'aa'];$result = $user->save($data);

因为这种方式首先得取得查询条件对应数据的模型类实例(取得的数据会保存在模型类实例的 data 属性(数组)里),然后模型类实例调用 save 方法的时候就会自动地使用自身 data 属性里的主键作为更新条件,所以不需要在 save 方法的参数里填写任何更新条件。

特别提示

这种更新方式是使用主键作为更新条件的,就算在 save 方法的第二个参数里填入其他的更新条件也是没用的,如下

$user = User::get(1);$data = ['username' => 'a'];$user->save($data, ['status' => 1]);

在 save 方法的第二个参数填入另外一个更新条件 status = 1

生成的 SQL 如下

UPDATE `user` SET `username` = 'a' WHERE `id` = 1

很显然,只会使用到主键 id ,而 status = 1 是失效的

2、不经过查询数据,直接使用模型类的实例进行更新

$user = new User();$data = ['username' => 'a'];$where = ['id' => 1];$result = $user->save($data, $where);

因为这种方式没有像第一种方式先取得某条记录的模型类实例(没有先取得某条记录的主键),所以这种方式调用 save 方法的时候就需要填写更新条件,更新条件并不一定是主键,可以是其他字段,所以当前方法可以一次性更新多条数据,如下

$user = new User();$data = ['status' => 1];$where = ['status' => 0];$user->save($data, $where);

把当前 User 模型对应的数据表中的 status 字段值等于1的行的 status 字段值更改为 0 

生成的 SQL 如下

UPDATE `user` SET `status` = 1 WHERE `status` = 0

版本差异

根据 ThinkPHP 的版本的不同,save 方法的主键的写法也有所不同,tp5.1 的 save 方法的主键必须写在第二个参数中(如上 $where),如果主键写在第一个参数中(如下 $data)save 方法将无法自动识别出主键,如下

$user = new User();$data = ['username' => 'aa', 'id' => 1];$user->save($data);

因为 save 方法无法自动识别出主键,所以当前 save 方法执行的是新增操作

如果想要 save 方法自动识别出主键,需要在save 方法前面调用 isUpdate 方法,指明该方法执行的是更新操作,如下

$data = ['username' => 'a','id' => 1];$result = $user->isUpdate()->save($data);

执行成功

tp5 版本可以在第一个参数里自动识别出主键,如下

$data = ['username' => 'a','id' => 1];$result = $user->save($data);

执行成功

返回值

V5.1.6+版本以前

save 方法返回影响的记录数

V5.1.6+版本以后

统一返回布尔值,如果执行 save 方法成功则返回 true(哪怕更新的行数是 0 也是返回 true ),并只有当 before_update 事件返回 false 的时候返回 false

重要提醒

从 V5.1.6+版本开始,save 方法只管执行 SQL 不管 SQL 执行后的结果,执行 SQL 成功则返回 true(哪怕更新的行数是 0 也是返回 true )

save 方法无论更新条件的字段值是否存在都可以执行更新并返回 true 而且不会有任何错误提示,所以更新前要先确保更新条件的字段值存在。

 3、和静态方法 update 一样,执行 save 方法成功不代表更新数据成功,如果当前更新数据的字段名在数据库内是不存在的, save 方法是不会向数据库发送 SQL 语句的,测试如下

$user = new User();$data = ['name' => 'a'];// name 字段在表结构中是不存在的$where = ['id' => 1];$user->save($data,$where);

  因为模型在执行更新操作前,会发送一条 SQL 语句获得表结构,如下

 SHOW COLUMNS FROM `user`

因为 name 字段在表结构中是不存在的,所以 save 方法是不会向数据库发送 SQL 语句的,而且 save 方法不会有任何错误提示,依然能返回 true,如下

bool(true)

更重要提醒

save 方法会修改调用它的对象的数据

$obj = new User();$user = $obj->find(1);echo ("
");var_dump($user);echo ("
");//更新前的 User 类实例object(app\index\model\User)#49 (2) { ["data"]=> array(9) { ["id"]=> int(1) ["username"]=> string(1) "a" ["password"]=> string(32) "47bce5c74f589f4867dbd57e9ca9f808" ["email"]=> NULL ["mobile"]=> NULL ["level"]=> int(1) ["status"]=> int(0) ["create_time"]=> int(1667095117) ["update_time"]=> int(1667368159) } ["relation"]=> array(0) { }}//执行更新$data = ['username' => 'aa', 'status' => 1];$user->save($data);echo ("
");var_dump($user);echo ("
");//执行更新后的 User 类实例object(app\index\model\User)#49 (2) { ["data"]=> array(9) { ["id"]=> int(1) ["username"]=> string(2) "aa" ["password"]=> string(32) "47bce5c74f589f4867dbd57e9ca9f808" ["email"]=> NULL ["mobile"]=> NULL ["level"]=> int(1) ["status"]=> int(1) ["create_time"]=> int(1667095117) ["update_time"]=> int(1667368159) } ["relation"]=> array(0) { }}

如上,User 类实例的 username 已经从 a 变成了 aa,status 已经从 0 变成1,和 save 方法更新数据库里的数据是保持一致的。

更更重要提醒

因为模型的新增方法和更新方法都是 save 方法,所以 tp5 框架有一套默认的规则来识别当前 save 方法要执行新增操作还是更新操作

不查询数据,直接模型对象调用 save 方法,表示新增

查询数据后调用 save 方法表示更新

save 方法传入更新条件表示更新

可以在执行 save 方法前执行 isUpdate ( true ) 方法指定当前 save 方法执行更新操作

不要用同一个模型类实例执行多次 save 方法,会导致部分重复数据不再更新,正确的方式应该是先查询后更新或者使用模型类的 update 方法更新

来源地址:https://blog.csdn.net/weixin_44161401/article/details/127615917

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯