ThinkPHP 8模型与数据的插入、更新、删除

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客

《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书

使用VS Code开发ThinkPHP项目-CSDN博客

编程与应用开发_夏天又到了的博客-CSDN博客

8.1 模型定义

定义模型非常简单,继承think\Model即可。下面是一个用户模型的示例:

复制代码
<?php
namespace app\model;

use think\Model;

class User extends Model
{

}

默认情况下,模型类名是去除表前缀的数据表名称,采用大驼峰命名法。比如下面的示例:

  • User <-> think_user
  • UserWallet <-> think_user_wallet

模型的$table属性可以手动指定数据表名称,下面是一个数据表为users的模型示例:

【示例8-1】

复制代码
<?php
namespace app\model;

use think\Model;

class User extends Model
{
    protected $table='users'; // 手动指定数据表名称

}

其他常用的模型属性包括pk和connection。pk用来指定主键字段,默认为id,如果数据表主键不是id,则需要重新定义。connection用来指定模型使用的数据库连接。

下面是一个指定主键和数据库连接的示例。

【示例8-2】

复制代码
<?php
namespace app\model;

use think\Model;

class User extends Model
{
    protected $pk = 'user_id';         // 指定主键,多对多关联中必须指定主键
    protected $connection = 'user';    // 手动指定数据表名称
}

模型字段用来指定模型属性的数据类型,推荐每个模型类都进行定义,ThinkPHP 8默认会自动获取数据表的字段类型(需要查询一次数据库)。在生产实践中一般会开启字段缓存,以避免频繁获取字段类型的开销。

模型的数据字段和对应数据表的字段是对应的,默认会自动获取(包括字段类型),但自动获取会导致增加一次查询(可以开启字段缓存功能),因此需要在模型中明确定义字段信息以避免多一次查询的开销。下面是一个手动定义模型字段的示例。

【示例8-3】

复制代码
<?php
namespace app\model;

use think\Model;

class User extends Model
{
    // 设置字段信息
    protected $schema = [
        'id'          => 'int',
        'username'        => 'string',
        'password'      => 'string',
		'age' => 'int',
        'balance'       => 'float',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];
}

上述代码中,模型字段对应数据库中的User表字段,schema属性需要定义所有字段。如果只需要手动指定某些字段的数据类型,则可以使用type属性,示例如下:

【示例8-4】

复制代码
<?php
namespace app\model;

use think\Model;

class User extends Model
{
    // 设置字段信息
    protected $type = [
        'balance'       => 'float',
    ];
}

8.2 插入数据

使用模型插入数据和查询构造器插入数据,最大的不同是模型会执行修改器、自动完成等逻辑,而数据库操作只是单纯的数据插入。

在调用模型实例的save方法插入数据时,如果插入成功,则返回true,否则会抛出异常。

【示例8-5】

本示例演示每个字段单独赋值。首先在mydb库中创建一张表,语句为:

复制代码
CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `nickname` varchar(45) NOT NULL,
  `status` int DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb3;

控制器User代码如下:

复制代码
<?php
namespace app\controller;
 
use app\model\UserModel;
 
class User {
    public function create() {
        $user = new UserModel();
        $data = [
            'name' => 'John Doe',
            'nickname' => 'John Bull',
            'status' => 1
        ];
        $result = $user->save($data);
        if ($result) {
            return '创建成功';
        } else {
            return '创建失败';
        }
    }
}

对应的Model为app\model\UserModel.php,代码如下:

复制代码
<?php
namespace app\model;
 
use think\Model;
 
class UserModel extends Model {
    // 设置当前模型对应的完整数据表名称
    protected $table = 'users';
 
    // 设置模型名称
    protected $name = 'user';
 
    // 设置可以批量赋值的字段列表
    protected $field = ['id', 'name', 'nickname', 'status'];
}

启动服务器,在浏览器中访问http://localhost:8000/user/create,页面将提示"创建成功"。当然,ThinkPHP 8也提供批量赋值的方法:

复制代码
$user = new User;
$user->save([
	'name' => 'Bruce Lee',
     'nickname' => 'Lee three foots',
     'status' => 1
]);
  1. REPLACE语句插入

REPLACE语句在数据库中通常用于插入新行或更新现有行。其工作原理类似于INSERT语句,但当新行与一个已有的行(根据PRIMARY KEY或UNIQUE索引)产生唯一性约束冲突时,旧行将被删除,然后新行被插入。因此,它可以视为一个删除(如果有需要)和插入的组合操作。

调用模型的replace方法可以进行REPLACE插入:

复制代码
$user = new User;

$user->replace()->save([

    'username' => 'test',

    'password' => password_hash('test', PASSWORD_DEFAULT);

]);
  1. 批量插入

调用模型实例的saveAll方法可以批量插入数据。当数据行包含主键时,ThinkPHP 8会执行更新操作,否则执行插入操作,代码如下:

复制代码
$user = new User;

$list = [

    ['name'=> 'test','age' => 20], // 识别为插入操作

    ['id' => 2,'name'=> 'test1','age' => 21], // 识别为更新操作

];

$user->saveAll($list);
  1. create方法插入

使用模型类的create方法插入数据是一种常用的方法,它可以返回模型实例,代码如下:

复制代码
$user = User::create([

    'name'  =>  'test',

    'age' =>  20

]);

8.3 更新数据

save方法会自动根据是否有主键来决定执行插入和更新操作,无须开发者手动调用更新方法。对于更新操作,一般需要先查询出模型实例,给对应的字段赋值,最后调用save方法更新数据,下面是一个示例:

复制代码
$user = User::where('username','test')->find();
if(!empty($user)) {
    $user->age = 20;
    $user->save();
}

还可以使用模型类的update方法更新数据,返回对应的模型实例:

复制代码
User::update(['age' => 20], ['id' => 1]);

8.4 删除数据

使用模型来删除数据,会执行模型的事件处理逻辑;而直接使用查询构造器删除数据,则不会执行模型的事件处理逻辑。下面是几种删除数据的方法:

复制代码
$user = User::find(1);
$user->delete(); // 调用模型实例的delete方法

User::destroy(1); // 静态方法删除
User::destroy([1,2,3]); // 支持批量删除多个数据

User::where('age', '<', 20)->delete(); // 基于where条件删除

相关推荐
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip14 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒14 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog25014 天前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis14 天前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel