我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

使用Go语言返回值类型推断构建可扩展的服务

go 语言中的返回值类型推断是一种功能,可让编译器自动推断函数或方法返回值的类型,从而简化代码。通过使用赋值运算符 :=,编译器使用函数上下文信息推断返回值类型。该功能适用于从数据库提取数据并返回 json 响应等场景,但可能不适用于返回特
使用Go语言返回值类型推断构建可扩展的服务
2024-04-30

PHP 中是否可以使用动态类型来定义函数返回值的类型?

尽管 php 是一种动态类型语言,但函数返回值的类型必须是静态的。php 不允许使用动态类型来定义返回值的类型,这有助于在编译时进行类型检查和类型推断,确保程序的健壮性和可靠性。PHP 中使用动态类型定义函数返回值的类型什么是动态类型?
PHP 中是否可以使用动态类型来定义函数返回值的类型?
2024-04-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录