ThinkPHP8学习篇(八):数据库(四)

在数据库操作的完整链路中,除了基础查询与进阶查询能力外,查询事件的钩子机制、数据获取的格式化处理、事务操作的原子性保障以及数据集的高效处理,共同构成了数据库操作的闭环增强体系,是提升代码健壮性与开发效率的重要支撑。本篇作为数据库系列文章的最后一篇,学习核心内容将集中在查询事件的注册与触发机制、获取器对数据输出的格式化处理、事务操作的开启/提交/回滚流程、以及数据集的遍历与转换等实用功能上。本篇文章将记录 ThinkPHP 数据库操作中这些增强特性的学习过程。


一、查询事件

数据库操作的回调也称为查询事件,是针对数据库的CURD操作而设计的回调方法,主要包括:

事件

描述

before_select

select查询前回调

before_find

find查询前回调

after_insert

insert操作成功后回调

after_update

update操作成功后回调

after_delete

delete操作成功后回调

使用 Db 类的 event 方法注册数据库查询事件。注册的代码可以写入到 app/AppService.php 中的 register() 服务注册方法中。

示例

// 代码位于 app/AppService.php 中的 register 方法内
public function register()
{
    // 注册 before_select 事件
    Db::event('before_select', function($query) {
        // 事件处理,可以编写对应的处理代码
        // 在这里也可以对 $query 进行操作,例如:在当前的 select 查询中对查询结果根据 id 进行 desc 排序
        $query->order('id', 'asc');
    });
}

不需要在事件中返回任何东西。

同一个查询事件可以注册多个响应执行。查询事件的方法参数只有一个:当前的查询对象。但可以通过依赖注入的方式添加额外的参数。

二、获取器

在 ThinkPHP 中,获取器是用于对字段值进行格式化处理的特殊方法。它允许你在获取字段数据时,自动对原始数据进行加工、转换或处理,而无需在每次使用数据时手动处理。

Db 类可以支持获取器定义,例如:

Db::table('user')->withAttr('name', function($value, $data) {
    // 将 name 字段的值会统一进行小写转换
    return strtoupper($value);
})
->select();

获取器方法支持传入两个参数,第一个参数是当前字段的值,第二个参数是所有的数据。

withAttr 方法可以多次调用,对多个字段定义获取器。

新版本增加了查询结果处理机制,使用 filter 方法可以更方便的处理查询结果数据:

Db::table('user')->filter(function($user) {
    // $user 为当前查询记录
    $user['name'] = strtoupper($user['name']); // 将 name 字段的值会统一进行小写转换
    return $user; // 需要 return 返回更改的内容
})
->select();

三、事务操作

使用事务处理的话,需要数据库引擎支持事务处理。比如 MySQLMyISAM 不支持事务处理,需要使用 InnoDB 引擎。

最简单的方式是使用 transaction 方法操作数据库事务,当闭包中的代码发生异常会自动回滚。例如:

Db::transaction(function () {
    Db::table('user')->find(1);
    Db::table('user')->delete(1);
});

也可以手动控制事务。例如:

// startTrans() 方法启动事务
Db::startTrans();
try {
    Db::table('user')->find(1);
    Db::table('user')->delete(1);
    // commit() 方法提交事务
    Db::commit();
} catch (\Exception $e) {
    // rollback() 方法回滚事务
    Db::rollback();
}

注意:在事务操作的时候,确保数据库连接使用的是同一个。

四、数据集

数据库的查询结果默认返回数据集对象。

示例

// 获取数据集
$users = Db::name('user')->select();
// 遍历数据集
foreach($users as $user){
    echo $user['name'];
    echo $user['id'];
}

返回的数据集对象是 think\Collection,提供了和数组无差别用法,并且另外封装了一些额外的方法。

可以直接使用数组的方式操作数据集对象。例如:

// 获取数据集
$users = Db::name('user')->select();
// 直接操作第一个元素
$item  = $users[0];
// 获取数据集记录数
$count = count($users);
// 遍历数据集
foreach($users as $user){
    echo $user['name'];
    echo $user['id'];
}

需要注意的是,如果要判断数据集是否为空,不能直接使用 empty 方法判断,而必须使用数据集对象的 isEmpty 方法判断。例如:

$users = Db::name('user')->select();
if($users->isEmpty()){
    echo '数据集为空';
}

Collection 类主要包含以下方法:

方法

描述

isEmpty

是否为空

toArray

转换为数组

all

所有数据

merge

合并其它数据

diff

比较数组,返回差集

flip

交换数据中的键和值

intersect

比较数组,返回交集

keys

返回数据中的所有键名

pop

删除数据中的最后一个元素

shift

删除数据中的第一个元素

unshift

在数据开头插入一个元素

push

在结尾插入一个元素

reduce

通过使用用户自定义函数,以字符串返回数组

reverse

数据倒序重排

chunk

数据分隔为多个数据块

each

给数据的每个元素执行回调

filter

用回调函数过滤数据中的元素

column

返回数据中的指定列

sort

对数据排序

order

指定字段排序

shuffle

将数据打乱

slice

截取数据中的一部分

map

用回调函数处理数组中的元素

where

根据字段条件过滤数组中的元素

whereLike

Like查询过滤元素

whereNotLike

Not Like过滤元素

whereIn

IN查询过滤数组中的元素

whereNotIn

Not IN查询过滤数组中的元素

whereBetween

Between查询过滤数组中的元素

whereNotBetween

Not Between查询过滤数组中的元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值