illuminate/database 使用 四

2023-11-27 11:15
文章标签 使用 database illuminate

本文主要是介绍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 使用 四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427554

相关文章

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

SQL server数据库如何下载和安装

《SQLserver数据库如何下载和安装》本文指导如何下载安装SQLServer2022评估版及SSMS工具,涵盖安装配置、连接字符串设置、C#连接数据库方法和安全注意事项,如混合验证、参数化查... 目录第一步:打开官网下载对应文件第二步:程序安装配置第三部:安装工具SQL Server Manageme

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.