hyperf 三十一 极简DB组件

一 安装及配置

composer require hyperf/db
php bin/hyperf.php vendor:publish hyperf/db

默认配置 config/autoload/db.php 如下,数据库支持多库配置,默认为 default

配置项类型默认值备注
driverstring数据库引擎 支持 pdomysql
hoststringlocalhost数据库地址
portint3306数据库地址
databasestring数据库默认 DB
usernamestring数据库用户名
passwordstringnull数据库密码
charsetstringutf8数据库编码
collationstringutf8_unicode_ci数据库编码
fetch_modeintPDO::FETCH_ASSOCPDO 查询结果集类型
pool.min_connectionsint1连接池内最少连接数
pool.max_connectionsint10连接池内最大连接数
pool.connect_timeoutfloat10.0连接等待超时时间
pool.wait_timeoutfloat3.0超时时间
pool.heartbeatint-1心跳
pool.max_idle_timefloat60.0最大闲置时间
optionsarrayPDO 配置

 具体接口可以查看 Hyperf\DB\ConnectionInterface

方法名返回值类型备注
beginTransactionvoid开启事务 支持事务嵌套
commitvoid提交事务 支持事务嵌套
rollBackvoid回滚事务 支持事务嵌套
insertint插入数据,返回主键 ID,非自增主键返回 0
executeint执行 SQL,返回受影响的行数
queryarray查询 SQL,返回结果集列表
fetcharray, object查询 SQL,返回结果集的首行数据
connectionself指定连接的数据库

二 使用

#使用 DB 实例
use Hyperf\Context\ApplicationContext;
use Hyperf\DB\DB;$db = ApplicationContext::getContainer()->get(DB::class);$res = $db->query('SELECT * FROM `user` WHERE gender = ?;', [1]);#使用静态方法
use Hyperf\DB\DB;$res = DB::query('SELECT * FROM `user` WHERE gender = ?;', [1]);#使用匿名函数自定义方法
#此种方式可以允许用户直接操作底层的 PDO 或者 MySQL,所以需要自己处理兼容问题
use Hyperf\DB\DB;$sql = 'SELECT * FROM `user` WHERE id = ?;';
$bindings = [2];
$mode = \PDO::FETCH_OBJ;
$res = DB::run(function (\PDO $pdo) use ($sql, $bindings, $mode) {$statement = $pdo->prepare($sql);$this->bindValues($statement, $bindings);$statement->execute();return $statement->fetchAll($mode);
});

三 测试

use Hyperf\DB\DB as AustereDb;
use Hyperf\Utils\ApplicationContext;public function testdb1() {$db = ApplicationContext::getContainer()->get(AustereDb::class);$res = $db->query('SELECT * FROM `push_recode` WHERE id = ?;', [1]);var_dump($res);$res = AustereDb::query('SELECT * FROM `push_recode` WHERE id = ?;', [1]);var_dump($res);$sql = 'SELECT * FROM `push_recode` WHERE id = ?;';$bindings = [1];$mode = \PDO::FETCH_NUM;$res = AustereDb::run(function (\PDO $pdo) use ($sql, $bindings, $mode) {$statement = $pdo->prepare($sql);$this->bindValues($statement, $bindings);$statement->execute();return $statement->fetchAll($mode);});var_dump($res);
}

 测试结果

array(1) {[0]=>array(4) {["id"]=>int(1)["is_push"]=>int(1)["push_time"]=>string(19) "2024-04-11 08:10:13"["created_at"]=>NULL}
}
array(1) {[0]=>array(4) {["id"]=>int(1)["is_push"]=>int(1)["push_time"]=>string(19) "2024-04-11 08:10:13"["created_at"]=>NULL}
}
array(1) {[0]=>array(4) {[0]=>int(1)[1]=>int(1)[2]=>string(19) "2024-04-11 08:10:13"[3]=>NULL}
}

可能由于版本问题,Hyperf\Context\ApplicationContext类不存在,所以使用Hyperf\Utils\ApplicationContext。

使用三种方法查询数据,使用DB实例、使用静态方法、使用PDO。

四 原理

获取容器参考hyperf console 执行-CSDN博客。

数据库配置获取参考hyperf console 执行-CSDN博客

用 php bin/hyperf.php vendor:publish hyperf/db 创建配置文件config\autoload\db.php后,其中使用.env文件。所以若项目数据库在.env中设置,配置文件可以不用改。

使用静态方法也是先获取容器,再调用对应方法。

使用run方法是根据配置文件获取数据库连接驱动,获取对应链接,默认是pdo。

若驱动为mysql,实际运行Hyperf\DB\MySQLConnection::run(Closure $closure)。

Closure类为一个闭包。

五 源码

#config\autoload\db.php
return ['default' => ['driver' => 'pdo','host' => env('DB_HOST', 'localhost'),'port' => env('DB_PORT', 3306),'database' => env('DB_DATABASE', 'hyperf'),'username' => env('DB_USERNAME', 'root'),'password' => env('DB_PASSWORD', ''),'charset' => env('DB_CHARSET', 'utf8mb4'),'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),'fetch_mode' => PDO::FETCH_ASSOC,'pool' => ['min_connections' => 1,'max_connections' => 10,'connect_timeout' => 10.0,'wait_timeout' => 3.0,'heartbeat' => -1,'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60),],'options' => [PDO::ATTR_CASE => PDO::CASE_NATURAL,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,PDO::ATTR_STRINGIFY_FETCHES => false,PDO::ATTR_EMULATE_PREPARES => false,],],
];
#Hyperf\DB\DBprotected $poolName;public function __construct(PoolFactory $factory, string $poolName = 'default'){$this->factory = $factory;$this->poolName = $poolName;}public static function __callStatic($name, $arguments){$container = ApplicationContext::getContainer();$db = $container->get(static::class);return $db->{$name}(...$arguments);}public function __call($name, $arguments){$hasContextConnection = Context::has($this->getContextKey());$connection = $this->getConnection($hasContextConnection);try {$connection = $connection->getConnection();$result = $connection->{$name}(...$arguments);} catch (Throwable $exception) {$result = $connection->retry($exception, $name, $arguments);} finally {if (! $hasContextConnection) {if ($this->shouldUseSameConnection($name)) {// Should storage the connection to coroutine context, then use defer() to release the connection.Context::set($contextKey = $this->getContextKey(), $connection);defer(function () use ($connection, $contextKey) {Context::set($contextKey, null);$connection->release();});} else {// Release the connection after command executed.$connection->release();}}}return $result;}private function getContextKey(): string{return sprintf('db.connection.%s', $this->poolName);}protected function getConnection(bool $hasContextConnection): AbstractConnection{$connection = null;if ($hasContextConnection) {$connection = Context::get($this->getContextKey());}if (! $connection instanceof AbstractConnection) {$pool = $this->factory->getPool($this->poolName);$connection = $pool->get();}return $connection;}
#Hyperf\DB\Pool\PoolFactoryprotected $container;public function __construct(ContainerInterface $container){$this->container = $container;}public function getPool(string $name){if (isset($this->pools[$name])) {return $this->pools[$name];}$config = $this->container->get(ConfigInterface::class);$driver = $config->get(sprintf('db.%s.driver', $name), 'pdo');$class = $this->getPoolName($driver);$pool = make($class, [$this->container, $name]);if (! $pool instanceof Pool) {throw new InvalidDriverException(sprintf('Driver %s is not invalid.', $driver));}return $this->pools[$name] = $pool;}protected function getPoolName(string $driver){switch (strtolower($driver)) {case 'mysql':return MySQLPool::class;case 'pdo':return PDOPool::class;}if (class_exists($driver)) {return $driver;}throw new DriverNotFoundException(sprintf('Driver %s is not found.', $driver));}
#Hyperf\DB\Pool\MySQLPoolprotected function createConnection(): ConnectionInterface{return new MySQLConnection($this->container, $this, $this->config);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2981543.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

投票刷礼物链接怎么弄?最新投票活动创建系统源码 轻松创建活动

投票刷礼物链接怎么弄?投票活动创建系统的作用和功能多种多样,为用户提供一个便捷、高效且功能强大的平台,用于创建、管理和执行各种投票活动。分享一个最新投票活动创建系统源码,源码开源可二开,含完整代码包和详细搭…

探索人工智能的边界:GPT 4.0与文心一言 4.0免费使用体验全揭秘!

探索人工智能的边界:GPT与文心一言免费试用体验全揭秘! 前言免费使用文心一言4.0的方法官方入口进入存在的问题免费使用文心一言4.0的方法免费使用GPT4.0的方法官方入口进入存在的问题免费使用GPT4.0的方法前言 未来已来,人工智能已经可以帮助人们完成许多工作了,不少工作…

自动批量将阿里云盘文件发布成WordPress文章脚本源码(以RiPro主题为例含付费信息下载地址SEO等自动设置)源码

背景 很多资源下载站,付费资源下载站,付费内容查看等都可以用WordPress站点发布内容,这些站点一般会基于一个主题,付费信息作为文章附属的信息发布,底层存储在WP表里,比如日主题,子比主题等。 …

凌恩病原微生物检测系统上线啦,助力环境病原微生物检测

病原微生物是指能够引起人类或动物疾病的微生物,包括病毒、细菌、真菌、衣原体和支原体等。病原微生物可以通过空气、体液等介质传播,危害人体健康,造成财产损失。因此,快速、准确地检测病原微生物对于疫情防控和保障人民生命健康…

Android SDK Manager安装Google Play Intel x86 Atom_64 System Image依赖问题

Package Google Play Intel x86 Atom_64 System Image,Android API R, revision 2 depends on SDK Platform Android R Preview, revision 2 问题 一开始以为网络还有依赖包没有勾选,尝试了很多次,勾选这边报错对应的license即可。此时点击一下其他licen…

Redis事务全解析:从MULTI到EXEC的操作指南!

【更多精彩内容,欢迎关注小米的微信公众号“软件求生”】 亲爱的粉丝朋友们,大家好!今天我们要讨论的主题是Redis的事务。Redis作为一款优秀的NoSQL数据库,凭借其高性能和灵活性广受欢迎。事务是Redis的一项关键功能,它为我们提供了一种在数据操作中确保一致性的机制。接…

atlas 500容器(ubuntu20.04)搭建

1.docker 及环境搭建略 2.宿主机驱动安装略 3.宿主机中能正确使用npu-smi 4.docker 拉取略 5.docker 容器启动 docker run -itd --device/dev/davinci0 --device/dev/davinci_manager --device/dev/devmm_svm --device/dev/hisi_hdc -v /run/board_cfg.ini:/run/b…

博士困境::博士毕业出路何在

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验,帮助大家尽早适应研究生生活,尽快了解科研的本质。祝一切顺利!—…

X86与FPGA相结合,基于PIB的AI开发——人体姿态识别

人体姿态估计是计算机视觉领域中用于理解和分析人类行为的一个关键技术。它主要涉及到检测和识别图像或视频中人体的各个关键点,并预测这些关键点之间的空间关系,从而构建出人体的骨架模型。 本文将介绍基于PIB板的人体姿态估计案例。这是一个交互式的实…

3月黄油奶酪行业数据分析:安佳和妙可蓝多领军市场

近些年来,随着新消费主义盛行,老少皆宜的黄油和奶酪逐渐成为都市年轻人的烘培“新宠”。 今年3月份,黄油奶酪表现的中规中矩,处在稳定发展阶段。根据鲸参谋数据显示,3月份,在线上综合电商平台(…

CSS3:border-image

<!DOCTYPE html> <html><head><meta charset"utf-8"> </head><body><p>原始图片</p><img src"./images/border1.png" alt""><p>一、</p><p>border: 27px solid transp…

VSCode通过跳板机免密连接远程服务器的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【电路笔记】-Hartley振荡器

Hartley振荡器 文章目录 Hartley振荡器1、概述2、Hartley振荡器电路3、并联Hartley振荡器电路4、示例5、使用运算放大器的Hartley振荡器6、总结1、概述 Hartley振荡器设计使用两个电感线圈与一个并联电容器串联,形成产生正弦振荡的谐振储能电路。 与Hartley振荡器不同,我们…

MPC的横向控制与算法仿真实现

文章目录 1. 引言2. 模型预测控制&#xff08;MPC&#xff09;2.1 基础知识2.2 MPC的整体流程2.3 MPC的设计求解 3. 车辆运动学MPC设计4. 算法和仿真实现 1. 引言 随着智能交通系统和自动驾驶技术的发展&#xff0c;车辆的横向控制成为了研究的热点。横向控制指的是对车辆在行…

dial tcp 192.168.0.190:443: connect: connection refused

1、场景 用nerdctl登录镜像仓库192.168.0.190&#xff08;Harbor&#xff09;&#xff0c;报错 ERRO[0006] failed to call tryLoginWithRegHost error"failed to call rh.Client.Do: Get \"https://192.168.0.190/v2/\": dial tcp 192.168.0.190:…

[羊城杯 2020]EasySer ---不会编程的崽

稍微带点反序列化&#xff0c;稍微。 常规扫描robots.txt,给出提示star1.php。 很明显的ssrf嘛。直接读 star1.php?pathhttp://127.0.0.1/star1.php <?php error_reporting(0); if ( $_SERVER[REMOTE_ADDR] "127.0.0.1" ) {highlight_file(__FILE__); } $f…

BDC报错信息查看

1.在事务代码st22的报错信息中下载本地文件 2.打开本地文件查看报错信息 3.在事务代码se91中输入对应消息类和消息编号 4.查看报错信息&#xff0c;根据报错信息取解决问题

Unity射击游戏开发教程:(5)使用 GetComponent 在 Unity 中进行脚本通信

我认为脚本通信是刚开始使用 Unity 时较难掌握的概念之一,我将继续讨论这个概念。在本文中,我将介绍如何在游戏对象发生碰撞时使用 GetComponent 来访问另一个脚本。 在这个游戏场景中,我有两个游戏对象,它们都有自己的脚本,需要进行通信。我们有玩家脚本和敌人脚本。Enem…

手撕netty源码(一)- NioEventLoopGroup

文章目录 前言一、NIO 与 netty二、NioEventLoopGroup 对象的创建过程2.1 创建流程图 前言 本文是手撕netty源码系列的开篇文章&#xff0c;会先介绍一下netty对NIO关键代码的封装位置&#xff0c;主要介绍 NioEventLoopGroup 对象的创建过程&#xff0c;看看new一个对象可以做…

水位传感器优点有哪些

水位传感器是一种用于检测液体水位的重要设备&#xff0c;在各种工业和民用场景中起着至关重要的作用。其中&#xff0c;光学液位传感器作为一种先进的水位检测技术&#xff0c;在市场上备受青睐&#xff0c;其优点主要包括以下几个方面。 光学液位传感器内部所有元器件均经过…