在其他情况下,项目需要连接多个数据库也是常见的需求。解决方案可以有多种,简单的方案,可以通过配置直接实现,但有一定局限性。复杂的方案,能解决更多应用场景遇到的问题并能更好满足约束限制。

这一章,将带你开启一段组合爆炸的神奇旅程。但本质就看实际有多少个数据库,以及最终有多少个NotORM实例。请记住这个经验法则:

一个数据库,对应一个NotORM实例;但一个NotORM实例可以对应多个数据库。

首先,通过./config/dbs.php的简单配置,就能实现连接多个数据库。

假设我们有两个数据库:第一个数据库:db_1

第二个数据库:db_1

假设都是MySQL数据库,按前面介绍的格式,则可以在./config/dbs.php文件中配置:

return array(

/**

* DB数据库服务器集群

*/

'servers' => array(

// 第一个数据库

'db_master' => array( //服务器标记

'host' => '127.0.0.1', //数据库域名

'name' => 'db_1', //数据库名字

'user' => 'root', //数据库用户名

'password' => '', //数据库密码

'port' => 3306, //数据库端口

'charset' => 'UTF8', //数据库字符集

),

// 第二个数据库

'db_other' => array( //服务器标记

'host' => '192.168.1.100', //数据库域名

'name' => 'db_2', //数据库名字

'user' => 'root', //数据库用户名

'password' => '', //数据库密码

'port' => 3306, //数据库端口

'charset' => 'UTF8', //数据库字符集

),

),

// 略……

第二步,再继续配置,不同的数据库表使用哪个数据库。参考分表配置的格式,只是这里是一个极端,即全部的分表只都有一张表,可以这样配置:

'tables' => array(

// 库表:db_1.user

'user' => array(

'prefix' => 'tbl_',

'key' => 'id',

'map' => array(

array('db' => 'db_master'),

),

),

// 库表:db_2.log

'log' => array(

'prefix' => 'tbl_',

'key' => 'id',

'map' => array(

array('db' => 'db_other'),

),

),

),

上面配置,分别配置了user用户表用db_1,log日志表用db_2。其他依此类推。

最后,在Model层编写的代码和平时一样即可。

namespace App\Model;

use PhalApi\Model\NotORMModel as NotORM;

class User extends NotORM {

public function count() {

// user表查db_1

return $this->getORM()->count();

}

}

// 另外的log表

class User extends NotORM {

public function count() {

// log日记表查db_2

return $this->getORM()->count();

}

}

至此,我们就可以通过配置来实现连接多个数据库。当前,整体架构如下:

但局限是:局限1:不同数据库不能有同名数据库表,否则会表名冲突。可以通过加前缀区分

局限2:只支持PhalApi默认的数据库类型,例如:MySQL

/**

* 增加pdo_dblib 和freetds 支持 mssql. 前提需支持 pdo_dblib,和freetds

* 1,通过phpinfo查看 PDO drivers中是否包含dblib

* 2,再终端输入命令测试本机是都可以正常链接你的数据库,比如: tsql -H 192.168.1.100 -p 1433 -U sa -P 1111

* 如果命令无效,则需要安装freetds

* ref:https://www.php.net/manual/en/pdo.drivers.php

*/

'db_sqlserver' => array( //服务器标记

'type' => 'dblib_sqlserver', //数据库类型,暂时只支持:mysql, sqlserver(需要sqlsrv驱动), dblib_sqlserver(需要pdo_dblib+freetds)

'host' => '192.168.1.100', //数据库域名

'name' => 'dbname', //数据库名字

'user' => 'sa', //数据库用户名

'password' => '12345678', //数据库密码

'port' => 1433, //数据库端口

'charset' => 'UTF8', //数据库字符集

),以上配置,需要PhalApi 2.7.0 及以上版本支持。

PhalApi 2.x 使用的是NotORM来进行数据库操作,而NotORM底层则是采用了PDO。目前,NotORM支持: MySQL, SQLite, PostgreSQL, MS SQL, Oracle (Dibi support is obsolete)。

当需要支持多个数据库时,可以按以下步骤来实现,共分为两大部分。第一部分,实现其他数据库的连接;第二部分,实现多个数据库共存。

第一部分如下:第一步、每一个数据库,单独一份./config/dbs.php配置文件(可复制此文件,如:./config/dbs_2.php)

第三步、在./config/di.php文件中,为新的数据库连接注册新的notorm服务

接着,是第二部分:第四步、为新的数据库连接实现新的Model基类,继承并重载PhalApi\Model\NotORMModel::getORM($id = NULL)方法,返回第三步的notorm服务

第五步、在Model层,在具体的Model子类中,继承第四步的基类

第六步,完成,正常的数据库操作

如果只有一个数据库,但不是MySQL数据库,则只需要完成第一部分;如果有多个数据库,则需要完成第一部分和第二部分。下面通过一个示例来概括介绍。

先来提前预览整体的架构,方便全局把控和了解。

假设,我们现在需要连接三个数据库,分别是:

数据库类型数据库名称数据库域名数据库端口数据库账号数据库密码MySQLphalapi192.168.1.13306root123456Ms Serverphalapi_ms192.168.1.21433rootabcdefpostgreSQLphalapi_pg192.168.1.33306rootabc123

为了能同时使得这三个数据库,第一步,为这三个数据库,分别准备以下配置三个dbs.php文件。

MySQL默认数据库的配置文件./config/dbs.php:

return array(

'servers' => array(

'db_master' => array( //服务器标记

'host' => '192.168.1.1', //数据库域名

'name' => 'phalapi', //数据库名字

'user' => 'root', //数据库用户名

'password' => '123456', //数据库密码

'port' => 3306, //数据库端口

'charset' => 'UTF8', //数据库字符集

),

),

/**

* 自定义路由表

*/

'tables' => array(

//通用路由

'__default__' => array(

'prefix' => 'tbl_',

'key' => 'id',

'map' => array(

array('db' => 'db_master'),

),

),

),

);

MS Server的数据库配置文件,由于PhalApi 2.x内置已支持MS Server的连接,因此创建配置文件./config/dbs_ms.php,并放置:

return array(

'servers' => array(

'db_master' => array( //服务器标记

'type' => 'sqlsrv', // 指定使用sqlsrv

'host' => '192.168.1.2', //数据库域名

'name' => 'phalapi_ms', //数据库名字

'user' => 'root', //数据库用户名

'password' => 'abcdef', //数据库密码

'port' => 1433, //数据库端口

'charset' => 'UTF8', //数据库字符集

),

),

/**

* 自定义路由表

*/

'tables' => array(

//通用路由

'__default__' => array(

'prefix' => 'tbl_',

'key' => 'id',

'map' => array(

array('db' => 'db_master'),

),

),

),

);

最后,是postgreSQL数据库的配置,在PhalApi 2.6.0 版本前,框架不支持此类型的数据库连接,需要创建配置文件./config/dbs_pg.php:并放置:

return array(

'servers' => array(

'db_master' => array( //服务器标记

'type' => 'pgsql', // 指定使用pgsql

'host' => '192.168.1.3', //数据库域名

'name' => 'phalapi_pg', //数据库名字

'user' => 'root', //数据库用户名

'password' => 'abc123', //数据库密码

'port' => 3306, //数据库端口

'charset' => 'UTF8', //数据库字符集

),

),

/**

* 自定义路由表

*/

'tables' => array(

//通用路由

'__default__' => array(

'prefix' => 'tbl_',

'key' => 'id',

'map' => array(

array('db' => 'db_master'),

),

),

),

);

到这里,第一步完成。

第二步是,进行不同数据库的连接。参考PHP官方手册PHP: PDO - Manua,PDO可支持以下数据库的连接:MySQL (PDO)

MS SQL Server (PDO)

PostgreSQL (PDO)

SQLite (PDO)

Oracle (PDO)

Firebird (PDO)

CUBRID (PDO)

IBM (PDO)

Informix (PDO)

ODBC and DB2 (PDO)

4D (PDO)

在PhalApi 2.5.0 版本后,可内置支持MySQL (PDO)、MS SQL Server (PDO)、PostgreSQL (PDO),如果需要其他类型数据库的连接,则需要继承PhalApi\Database\NotORMDatabase::createPDOBy($dbCfg)接口,并实现指定数据库PDO的创建和连接。以PostgreSQL (PDO)为例,可以这样实现代码。创建./src/app/Common/MyPostgreDB.php文件,并放置以下代码。

namespace App\Common;

use PhalApi\Database;

use PhalApi\Database\NotORMDatabase;

class MyPostgreDB extends NotORMDatabase {

protected function createPDOBy($dbCfg)

{

$dsn = sprintf('%s:dbname=%s;host=%s;port=%d',

$dsn = sprintf('pgsql:dbname=%s;host=%s;port=%d',

$dbCfg['name'],

isset($dbCfg['host']) ? $dbCfg['host'] : 'localhost',

isset($dbCfg['port']) ? $dbCfg['port'] : 3306

);

);

$charset = isset($dbCfg['charset']) ? $dbCfg['charset'] : 'UTF8';

$pdo = new \PDO(

$dsn,

$dbCfg['user'],

$dbCfg['password']

);

$pdo->exec("SET NAMES '{$charset}'");

return $pdo;

}

}

在完成这些准备工作后,就可以在./config/di.php文件中,注册这些不同的数据库实例。在./config/di.php文件中添加以下代码。

// 数据操作 - 基于NotORM

$di->notorm = new NotORMDatabase($di->config->get('dbs'), $di->debug);

// 追加

// MS Server数据库

$di->notorm_ms = new NotORMDatabase($di->config->get('dbs_ms'), $di->debug);

// PostgreSQL数据库(切换成自己的新类)

$di->notorm_pg = new App\Common\MyPostgreDB($di->config->get('dbs_pg'), $di->debug);

下面进行第二部分,到了第四步,需要分别实现两个Model基类,分别用于MS Server数据库和PostgreSQL数据库。

首先,是MS Server数据库的Model基类,创建./src/app/Model/MSModelBase.php文件,代码如下:

namespace App\Model;

use PhalApi\Model\NotORMModel;

class MSModelBase extends NotORMModel {

protected function getORM($id = NULL) {

$table = $this->getTableName($id);

return \PhalApi\DI()->notorm_ms->$table; // 注意这一行,改为:notorm_ms

}

}

然后,对于PostgreSQL数据库也这类似这样,即添加./src/app/Model/PostgreModelBase.php文件,代码如下:

namespace App\Model;

use PhalApi\Model\NotORMModel;

class PostgreModelBase extends NotORMModel {

protected function getORM($id = NULL) {

$table = $this->getTableName($id);

return \PhalApi\DI()->notorm_pg->$table; // 注意这一行,改为:notorm_pg

}

}

当你完成到这里,恭喜你,离成功不远啦!剩下的就是使用,基本上和平常的Model使用是一样的。

第五步,在需要的Model子类中,继承对应的数据库基类。为方便区分,可以为不同的数据库划分不同的目录。例如,对于MS Server,创建目录./src/app/Model/MSServer。假设有一张user的表,则可以创建./src/app/Model/MSServer/User.php文件,放置代码:

namespace App\Model\MSServer;

use App\Model\MSModelBase;

class User extends MSModelBase { // 注意,这里换成新的基类

protected function getTableName($id) {

return 'user';

}

}

PostgreSQL和这类似,不再赘述。

最后一步,就可以正常使用啦。例如:

class User extends MSModelBase { // 注意,这里换成新的基类

protected function getTableName($id) {

return 'user';

}

public function count() {

return $this->getORM()->count();

}

}

搞定,收工!

对于PhalApi 2.8.0 及以上版本,框架进一步优化了多个数据库的支持。只需重载PhalApi\Model\NotORMModel::getNotORM(),就可以在Model实现一键切换数据库实例。

例如,默认代码是:

protected function getNotORM() {

return \PhalApi\DI()->notorm;

}

你可以在./config/di.php注入多个数据库后,例如前文提及的:$di->notorm_ms,和$di->notorm_pg,则可以:

namespace App\Model;

use PhalApi\Model\NotORMModel;

class MSModelBase extends NotORMModel {

protected function getNotORM() {

return \PhalApi\DI()->notorm_ms; // 切换数据库实例

}

}

相比之前Hard Code的方式,这样会更优雅。

在PhalApi中,数据库操作主要是基于NotORM来实现。而对于数据库的连接,以及对于分库分表,则可以通过配置或者自定义开发来扩展。这种组合是非常灵活、优雅且设计巧妙的。

与传统的框架不同的是,PhalApi天生就支持多个数据库、分表分库的配置。更多复杂的组合功能,可以在熟悉前面这些配置和策略后自由发挥。期待你的大作品!

phalapi 数据库锁_2.5 PhalApi 连接多个数据库相关推荐

  1. navicat无法连接远程mysql数据库_[数据库]Navicat Premium 解决无法连接远程mysql数据库问题...

    [数据库]Navicat Premium 解决无法连接远程mysql数据库问题 0 2018-07-18 00:00:15 问题原因 :  第一点 远程服务器数据库没有授权 第二点 远程连接数据库的端 ...

  2. 技术合集 | 【MySQL技术专题】「数据库锁技术」深入浅出透析MySQL数据库的锁基础概念和原理(上下全)

    上篇 前提介绍 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 本文内容 本文主要介绍:行级锁.表级锁.页级锁的相关概念以及原理介绍 本文主 ...

  3. 通达oa oracle数据库,通达OA 2016系统连接ORACLE 11g数据库(图文)

    通达OA应该对Oracle是支持的,在数据源里还有ERP数据源的选项有sqlserver和Oracle的选项呢. 使用OA连接Oracle还是需要一些设置的. 1.先下载Oracle的客户端支持程序 ...

  4. php mysqldb 数据库切换,Python MySQLdb模块连接操作mysql数据库实例

    mysql是一个优秀的开源数据库,它现在的应用非常的广泛,因此很有必要简单的介绍一下用python操作mysql数据库的方法.python操作数据库需要安装一个第三方的模块,在http://mysql ...

  5. 如何通过代码连接SQL Server数据库

    我们曾经为南方电网做过几个有关架空线路的科技项目,要趁着假期有整段的空闲时间,把这些代码整理一下,放入团队刚刚重构的代码库中. 由于这些项目使用的数据库为 SQL Server,所以在整理代码之前需要 ...

  6. Mysql之数据库锁(表锁和行锁)详解

    1. 什么是锁? 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种共享资源,如何保证数据并发访问的一致性.有效性 ...

  7. php5.6 win2008 mssql,Php5.6.31连接sqlserver 2008R2数据库问题sqlsrv(php5.3及以上版本)与mssql(php5.3以前版本)②...

    Php5.6.31连接sqlserver2008R2数据库 1.环境配置 Win7(win8.1)  64 +Apache2.4 + PHP5.6.31 + SQL Server 2008 R2数据库 ...

  8. 搭建WAMP5环境,连接SQL Server2005数据库问题汇总

    经过两周的测试.修改,终于将网上药品采购系统从公司内部OA系统中独立出来,用WAMP5重新搭建了PHP网上药品采购系统.现将遇到的问题汇总如下: 1.数据库连接失败的问题,提示 Fatal error ...

  9. visual studio2019连接SQL Server数据库,增删改查详细教程(C#代码)

    visual studio2019连接SQL Server数据库,增删改查详细教程(C#代码) 工具: 1.Visual Studio 2019 2.SQL Server数据库(我使用的2008) 操 ...

  10. linux连接本机mysql数据库,Linux中MySQL连接本机数据库客户端

    Linux中MySQL连接本机数据库客户端 Linux中MySQL连接本机数据库客户端 1.登入mysql数据库 2.找到要修改的位置 // 选定要用的数据库(用show databases;看完再u ...

最新文章

  1. JAVA 线程Join
  2. 在ssh项目中的中配置数据源c3p0
  3. C++ 栈和堆上建立对象的区别
  4. ZOJ 3720 Magnet Darts (计算几何,概率,判点是否在多边形内)
  5. 用O(1)的时间复杂度删除单链表中的某个节点
  6. poi的sax模式读取xls_POI SAX 如何修改大excel 文件内容-问答-阿里云开发者社区-阿里云...
  7. 直击“上云”痛点的 MSP 新生意,万博智云发布云原生迁移工具 HyperMotion 3.0
  8. openfire4.2.1 + smack4.2.2即时通信工具开发(android端登录、发送消息、接收消息)
  9. 电脑开热点手机无法连接,无法启用 Internet 连接共享.为 LAN 连接配置的 IP 地址需要使用自动 IP 寻址.
  10. 百度基础架构部马如悦:我的Hadoop…
  11. 关于Linux中批量配置SSH免密的一些笔记
  12. 如何用tushare复盘
  13. Git 工作常用命令行
  14. ICLR 2021|基于GAN的二维图像无监督三维形状重建
  15. Maven学习笔记,动力节点maven教程随堂笔记(史上最全)
  16. ICMP协议是什么协议?
  17. 中移M5311模块MQTT协议连接阿里云物联网平台(干货)
  18. 高仿小米时钟 - 使用Camera和Matrix实现3D效果
  19. 可知道我们十指交缠的那一夜;我们誓言到老的那一夜
  20. Java中PDF水印设置

热门文章

  1. python判断火车票座位是否靠窗_Python查询火车票(一)
  2. 移动端自适应方案(转载)
  3. 我为账户和推广计划指定了不同的推广地域,以哪一个为准?
  4. 用Python 统计、分析2020年江苏省事业单位招聘岗位 Excel 表格信息
  5. TSP问题(推销员问题)
  6. 推荐几款网页截图工具可以全屏截图,也可对图片编辑
  7. 定时网页截图php,浏览器实现网页定时自动截图
  8. doPost 乱码问题解决
  9. 1.6 判断一个字符串是否由重复子字符串组成
  10. ‘mvn‘不是内部或外部命令