【我是小白】如何切换数据库

我在dbs里面定义了多个数据库, 我已经注意到在 config 目录的 di.php 是初始化数据库链接, 但是目前始终是dbs里面定义的 默认数据库,我如何定义两个不同的数据库链接?(这个浅显的问题翻遍了文档也没有答案)
已邀请:

dogstar - PhalApi创始人

赞同来自:

文档在这:https://www.phalapi.net/wikis/2-12.html

在配置dbs.php文件时,
            'map' => array(
array('db' => 'db_A'), //默认,使用db_A数据库
),
db可用于指定数据库。也就是说,你可配置一个表,然后再指定它的db,就可以自动切换到对应的数据库了。

gogo7707

赞同来自:

感谢作者答复, 我觉得你这个路由设置 是分表分库是需要设置, 但是大部分情况下,我们做数据操作是很确定这个表是在哪个数据库以及什么服务器上都是很确定的,,感觉你这样不太直观,建议 di.php里面 的 创建数据库的语句增加这样的第三个参数
// 数据操作 - 基于NotORM
$di->notorm = new NotORMDatabase($di->config->get('dbs'), $di->debug,"db_2");
$di->notorm1 = new NotORMDatabase($di->config->get('dbs'), $di->debug,"db_master");
 
当指定第三个参数的时候,就是确定是指定哪个数据库,不要寻找路由;当第三个参数为空时就是按照原来的办法搜索路由,这样就两者兼顾了。
 
db_2 和db_master对应 dbs.php里面的数据库名称

return array(
    /**
     * DB数据库服务器集群
     */
    'servers' => array(
        'db_master' => array(                         //服务器标记
'type'      => 'mysql',             //数据库域名        
            'host'      => 'localhost',             //数据库域名
            'name'      => 'td_oa',               //数据库名字
            'user'      => 'root',                  //数据库用户名
            'password'  => '*HM2Ll!#7VCg1K_19F#3@tJ',                     //数据库密码
            'port'      => 3336,                  //数据库端口
            'charset'   => 'GBK',                  //数据库字符集
        ),
        'db_2' => array(                         //服务器标记
'type'      => 'sqlserver',             //数据库域名        
            'host'      => 'hmx.risedot.com',             //数据库域名
            'name'      => 'kaoqin',               //数据库名字
            'user'      => 'sa',                  //数据库用户名
            'password'  => '13602685392',                     //数据库密码
            'port'      => 1433,                  //数据库端口
            'charset'   => 'GBK',                  //数据库字符集
        ),        
    ),
 

dogstar - PhalApi创始人

赞同来自:

其实很简单的,不需要改动,现有的功能已经可以支持。可这样使用:
$di->notorm = new NotORMDatabase($di->config->get('dbs'), $di->debug);
$di->notorm1 = new NotORMDatabase($di->config->get('dbs1'), $di->debug);
只需要将dbs.php文件复制多一份到dbs1.php即可。

gogo7707

赞同来自:

按照你说的配置文件另外拷贝试过了, 不行
$di->notorm = new NotORMDatabase($di->config->get('dbs'), $di->debug); 
$di->notorm1 = new NotORMDatabase($di->config->get('dbs1'), $di->debug);
第一行是工作的, 第二行定义是成功的, 但是系统不会调用 $di->notorm1  这个, 也就是说,把第一行屏蔽掉, 原来工作正常的程序就会报错, 显示:
Notice: Trying to get property of non-object in D:\MYOA17\webroot\phalapi\vendor\phalapi\kernal\src\Model\NotORMModel.php on line 126 Fatal error: Call to a member function select() on a non-object in D:\MYOA17\webroot\phalapi\vendor\phalapi\kernal\src\Model\NotORMModel.php on line 30
 
是其他什么地方还需要修改吗?

gogo7707

赞同来自:

因为你的 $di-> notorm 是  写在 NotORMModel.php 里面的:
    protected function getORM($id = NULL) {
        $table = $this->getTableName($id);
        return \PhalApi\DI()->notorm->$table;
    }
所以 第二个数据源的实例 $di->notorm1 是不工作的, 找到了临时的解决方法,就是在需要第二个数据源的Model里面 重写 getORM函数 :
<?php
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Departments extends NotORM {
    protected function getORM($id = NULL) {
        $table = $this->getTableName($id);
        return \PhalApi\DI()->notorm1->$table;
    }    
}
现在 sqlserver 和 mysql  两个数据源可以共存, 并且各自读取数据正常了, 不过总觉得有点别扭,getORM应该返回当前实例的名称,而不是写死为 DI()->notorm  , 作者能改进下吗?
 

dogstar - PhalApi创始人

赞同来自:

感谢反馈,目前可先这样使用,我们再看下如何优化,谢谢。

要回复问题请先登录注册