illuminate/database 使用 四
文档:Hyperf
Database: Getting Started - Laravel 10.x - The PHP Framework For Web Artisans
因为hyperf使用illuminate/database,所以按照文章,看illuminate/database代码实现。
一、读写分离
根据文档读写的host可以分开。设置读写分离的前提,做数据库出从同步。
1.1 数据库主从同步
参考:mysql5.7 主从配置-CSDN博客
1.2 设置
配置中设置三个数据read、write、sticky。read、write都包含host数组,其配置会和主要配置合并。就是说,比如host相同,应该在read、write中设置对应数据,以覆盖主要设置。
sticky选项是一个可选值,可用于允许在当前请求周期内立即读取已写入数据库的记录。如果启用了sticky选项,并且在当前请求周期中对数据库执行了“写”操作,则任何进一步的“读”操作都将使用“写”连接。这确保了在请求周期内写入的任何数据都可以在同一请求期间立即从数据库中读回。
源码如下:
#Illuminate\Database\Connectors\ConnectionFactory
protected function getReadConfig(array $config){return $this->mergeReadWriteConfig($config, $this->getReadWriteConfig($config, 'read'));}
protected function getWriteConfig(array $config){return $this->mergeReadWriteConfig($config, $this->getReadWriteConfig($config, 'write'));}
protected function mergeReadWriteConfig(array $config, array $merge){return Arr::except(array_merge($config, $merge), ['read', 'write']);}#Illuminate\Database\Connection
public function getReadPdo(){if ($this->transactions > 0) {return $this->getPdo();}if ($this->readOnWriteConnection ||($this->recordsModified && $this->getConfig('sticky'))) {return $this->getPdo();}if ($this->readPdo instanceof Closure) {return $this->readPdo = call_user_func($this->readPdo);}return $this->readPdo ?: $this->getPdo();}
1.3 测试
配置如下
#config/database.php
return ['migrations' => '', //数据迁移//PDO文档 https://www.php.net/manual/zh/pdo.constants.php'default' => 'master','connections' => ['master' => ['driver' => 'mysql','host' => 'localhost','database' => 'test','username' => 'root','password' => 'qwe110110','charset' => 'utf8','collation' => 'utf8_general_ci','prefix' => '','port' => '3306','read' => ['host' => ['127.0.0.1'],'port' => '3307',],'write' => ['host' => ['127.0.0.1'],'port' => '3306',],],]
];
测试代码
function test1()
{new App();$query = "concat('-',id)";$as = "id";//$info1 = DbManager::table('userinfo')->select(['name'])->selectSub($query, $as)->addSelect(['age'])->get();$info1 = DbManager::table('userinfo')->select(['name'])->selectSub($query, $as)->addSelect(['age'])->get();var_dump($info1);$data = $info1->all();$insertData = ['name' => 'test1', 'age' => 1];$id = DbManager::table('userinfo')->insertGetId($insertData);var_dump($id);//exit;//$sql = "CONCAT('A-',name)";//$info2 = DbManager::table('userinfo')->selectSub($sql, "table")->toSql()->dump();
}
test1();
返回结果
string(29) "Illuminate\Support\Collection"
array(8) {[0] =>class stdClass#18 (3) {public $name =>string(3) "123"public $id =>string(2) "-1"public $age =>int(22)}[1] =>class stdClass#22 (3) {public $name =>string(5) "name2"public $id =>string(2) "-2"public $age =>int(13)}[2] =>class stdClass#23 (3) {public $name =>string(5) "name3"public $id =>string(2) "-3"public $age =>int(24)}[3] =>class stdClass#24 (3) {public $name =>string(5) "33321"public $id =>string(2) "-4"public $age =>int(0)}[4] =>class stdClass#25 (3) {public $name =>string(5) "test1"public $id =>string(2) "-5"public $age =>int(1)}[5] =>class stdClass#26 (3) {public $name =>string(5) "test1"public $id =>string(2) "-6"public $age =>int(1)}[6] =>class stdClass#27 (3) {public $name =>string(5) "test1"public $id =>string(2) "-7"public $age =>int(1)}[7] =>class stdClass#28 (3) {public $name =>string(5) "test1"public $id =>string(2) "-8"public $age =>int(1)}
}
int(9)
从库:
主库
测试成功~
1.4 返回数据处理
从测试结果看,返回的都是对象,因为默认使用PDO::FETCH_OBJ。
参考:PHP: PDO - Manual
源码如下
#Illuminate\Database\Capsule\Manager
public function __construct(Container $container = null){$this->setupContainer($container ?: new Container);// Once we have the container setup, we will setup the default configuration// options in the container "config" binding. This will make the database// manager work correctly out of the box without extreme configuration.$this->setupDefaultConfiguration();$this->setupManager();}
protected function setupDefaultConfiguration(){$this->container['config']['database.fetch'] = PDO::FETCH_OBJ;$this->container['config']['database.default'] = 'default';}
public function setFetchMode($fetchMode){$this->container['config']['database.fetch'] = $fetchMode;return $this;}#Illuminate\Database\Connection
protected $fetchMode = PDO::FETCH_OBJ;
public function select($query, $bindings = [], $useReadPdo = true){return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) {if ($this->pretending()) {return [];}// For select statements, we'll simply execute the query and return an array// of the database result set. Each element in the array will be a single// row from the database table, and will either be an array or objects.$statement = $this->prepared($this->getPdoForSelect($useReadPdo)->prepare($query));$this->bindValues($statement, $this->prepareBindings($bindings));$statement->execute();return $statement->fetchAll();});}
protected function prepared(PDOStatement $statement){$statement->setFetchMode($this->fetchMode);$this->event(new StatementPrepared($this, $statement));return $statement;}
想返回数组可以设置为PDO::FETCH_ASSOC。最简单的方法就是替换源码,二次开发最好就是用对象,或者写个对象转数组的方法,tp里面有源码。tp是查出来对象,可使用toArray()搞成数组。
get()返回的类是Illuminate\Support\Collection,此类中还有一些数据统计的方法,比如平均值之类。意思就是查出来数据再做数据统计。
二、多库配置
根据laravel文档:如果应用程序在config/database.php配置文件中定义了多个连接,则可以通过DB facade提供的连接方法访问每个连接。
use Illuminate\Support\Facades\DB;$users = DB::connection('sqlite')->select(/* ... */);
$pdo = DB::connection()->getPdo();
但是仅用这个库由于没有对应数据,会返回db类是null。
源码如下:
#Illuminate\Support\Facades\Facade
public static function getFacadeRoot(){return static::resolveFacadeInstance(static::getFacadeAccessor());}
public static function __callStatic($method, $args){$instance = static::getFacadeRoot();if (!$instance) {throw new RuntimeException('A facade root has not been set.');}return $instance->$method(...$args);}protected static function resolveFacadeInstance($name){if (is_object($name)) {return $name;}if (isset(static::$resolvedInstance[$name])) {return static::$resolvedInstance[$name];}if (static::$app) {return static::$resolvedInstance[$name] = static::$app[$name];}}
根据方法resolveFacadeInstance(),$name应该是‘db’,不是对象,$resolvedInstance、$app没有对应对象,所以返回空。估计得配合其他类库。比如hyperf中需要
composer require hyperf/database
那么不用其他类库怎么实现多库切换……
多库配置
return ['migrations' => '', //数据迁移//PDO文档 https://www.php.net/manual/zh/pdo.constants.php'default' => 'master','connections' => ['master' => ['driver' => 'mysql','host' => 'localhost','database' => 'test','username' => 'root','password' => 'mima','charset' => 'utf8','collation' => 'utf8_general_ci','prefix' => '','port' => '3306','read' => ['host' => ['127.0.0.1'],'port' => '3307',],'write' => ['host' => ['127.0.0.1'],'port' => '3306',],],'test' => ["driver" => "mysql","host" => "127.0.0.1","database" => "test1","username" => "root","password" => "mima",'charset' => 'utf8mb4','collation' => 'utf8mb4_unicode_ci','prefix' => '','port' => '3307',],],
];
function test2()
{$app = new App();$info = DbManager::connection('test')->table('userinfo')->where('id', '=', 1)->get();$info = $info->first();var_dump($info);
}test2();
返回数据
class stdClass#20 (2) {public $id =>int(1)public $name =>string(1) "1"
}
相关文章:

illuminate/database 使用 四
文档:Hyperf Database: Getting Started - Laravel 10.x - The PHP Framework For Web Artisans 因为hyperf使用illuminate/database,所以按照文章,看illuminate/database代码实现。 一、读写分离 根据文档读写的host可以分开。设置读写分…...

Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能
文章目录 Spring面向切面编程(AOP)什么是AOPSpring AOP and AspectJ AOP 的区别?Spring AOP中的动态代理如何理解 Spring 中的代理?解释一下Spring AOP里面的几个名词Spring在运行时通知对象Spring切面可以应用5种类型的通知:什么是切面 Aspe…...

vatee万腾的科技征途:Vatee独特探索的数字化力量
在数字化时代的浪潮中,Vatee万腾以其独特的科技征途成为引领者。公司在数字化领域的探索之路不仅是技术的创新,更是一种对未知的勇敢涉足,是对新时代的深刻洞察和积极实践。 Vatee万腾通过独特的探索,展示了在数字化征途上的创新力…...

MySQL学习day03
一、SQL图形化界面工具 常用比较常用的图形化界面有sqlyog、mavicat、datagrip datagrip工具使用相当方便,功能比前面两种都要强大。 DataGrip工具的安装和使用请查看这篇文档:DataGrip 安装教程 DML-介绍 DML全称是Data Manipulation Language(数据…...

《QT从基础到进阶·三十七》QWidget实现左侧导航栏效果
NavigationBarPlugin插件类实现了对左侧导航栏的管理,我们可以在导航栏插件中添加界面,并用鼠标点击导航栏能够切换对应的界面。 源码在文章末尾 实现效果如下: NavigationBarPlugin实现的接口如下: class NAVIGATIONBAR_EXP…...
sftp学习
什么是sftp? sftp的简单操作 远程连接 int RobostSftp::Init(QString ip,QString port,QString user_name, QString user_password) { int rc;session ssh_new();if (!session) {fprintf(stderr, "ssh initialization failed\n");// return 1…...

C++之STL库:string类(用法列举和总结)
前言 大家在学习STL库的时候一定要学会看英文文档,俗话说熟能生巧,所以还得多练!在使用string类之前,要包含头文件#include <string>和using namespace std; 文档链接:string - C Reference 一、string——构造…...

小程序中的大道理--综述
前言 以下将用一个小程序来探讨一些大道理, 这些大道理包括可扩展性, 抽象与封装, 可维护性, 健壮性, 团队合作, 工具的利用, 可测试性, 自顶向下, 分而治之, 分层, 可读性, 模块化, 松耦合, MVC, 领域模型, 甚至对称性, 香农的信息论等等. 为什么不用大程序来说大道理呢? …...
tlais智能学习辅助系统-修改部门功能实现
学习黑马程序员的JavaWeb课程,自己写的部门信息修改部分程序 控制层: //DeptController.java /** * 根据ID查询部门信息 * param id * return */ GetMapping("/{id}") public Result select(PathVariable Integer id){log.info("查询id…...

GLM: 自回归空白填充的多任务预训练语言模型
当前,ChatGLM-6B 在自然语言处理领域日益流行。其卓越的技术特点和强大的语言建模能力使其成为对话语言模型中的佼佼者。让我们深入了解 ChatGLM-6B 的技术特点,探索它在对话模型中的创新之处。 GLM: 自回归空白填充的多任务预训练语言模型 ChatGLM-6B 技…...
函数递归所应满足的条件
1.递归的概念 递归是学习C语⾔函数绕不开的⼀个话题,那什么是递归呢? 递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。 递归的思想: 把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但…...

Python入职某新员工大量使用Lambda表达式,却被老员工喷是屎山
Python中Lambda表达式是一种简洁而强大的特性,其在开发中的使用优缺点明显,需要根据具体场景权衡取舍。 Lambda表达式的优点之一是它的紧凑语法,适用于一些短小而简单的函数。这种形式使得代码更为精炼,特别在一些函数式编程场景中,Lambda表达式可以提高代码的表达力。此外…...
Android Bitmap保存成至手机图片文件,Kotlin
Android Bitmap保存成至手机图片文件,Kotlin fun saveBitmap(name: String?, bm: Bitmap) {val savePath Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString()if (!Files.exists(Paths.get(savePath))) {Log.d("保存文…...

frp V0.52.3 搭建
下载 https://github.com/fatedier/frp/releases/ 此版本暂时没有windows的,想在windows使用请下载v0.52.2 简易搭建 frps.toml的配置文件,以下12000、8500需要在云服务器中的防火墙中开放tcp # bindPort为frps和frpc通信的端口,需要在防…...
最近数据分析面试的一点感悟...
我是阿粥,也是小z 最近面了不少应届的同学(数据分析岗位),颇有感触,与各位分享。 简历可以润色,但要适度 运用一些原则,如STAR法则,让简历逻辑更清晰,条块分明࿰…...

ZYNQ_project:IIC_EEPROM
EEPROM简介: EEPROM(Electrically Erasable Progammable Read Only Memory, E2PROM)是指带电可擦可编程只读存 储器,是一种常用的非易失性存储器(掉电数据不丢失), E2PROM 有多种类型的产品,我…...
Leetcode 2940. Find Building Where Alice and Bob Can Meet
Leetcode 2940. Find Building Where Alice and Bob Can Meet 1. 解题思路2. 代码实现3. 算法优化 题目链接:2940. Find Building Where Alice and Bob Can Meet 1. 解题思路 这一题本质上又是限制条件下求极值的问题,算是我最不喜欢的题目类型之一吧…...

C++ 泛型编程,函数模版和类模版
1.泛型编程 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础 就比如说活字印刷术,就是提供一个模具,然后根据模具来印刷出不同的字。 泛型编程跟着类似,提供一个模版,根据这…...

【封装UI组件库系列】封装Button图标组件
封装UI组件库系列第四篇封装Button按钮组件 🌟前言 🌟封装Button组件 1.分析封装组件所需支持的属性与事件 支持的属性: 支持的事件: 2.创建Button组件 🌟封装功能属性 type主题颜色 plain是否朴素 loading等…...

windows系统mobaxterm远程执行linux上ssh命令
命令如下 start "" "%~dp0\MobaXterm_Personal_23.4.exe" -newtab "sshpass -p root ssh root192.168.11.92 mkdir 33" -p 是密码 左边是用户名,右边是服务器ip 后面跟的是服务器上执行的命令 第一次执行的时候要设置mobaxt…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...