laravel动态分库的实现

lumen默认支持多数据源,但如果系统存在多个结构相同的数据库实例,并根据某特定请求参数访问不同的实例,那么可以通过中间件实现动态配置。

1、在app/config/database.php文件中配置默认mysql数据库连接参数
2、在默认库中创建一个配置表,其中保存各数据库分库的配置,如下表(以corpid做分库条件),这个表只需要在主库中创建并维护

CREATE TABLE `corp_database` (
  `corpid` varchar(50) NOT NULL DEFAULT '' COMMENT '租户id',
  `read_host` varchar(100) NOT NULL DEFAULT '' COMMENT '读库地址',
  `read_port` int(11) NOT NULL DEFAULT '3306' COMMENT '读库端口',
  `read_database` varchar(100) NOT NULL DEFAULT '' COMMENT '读库数据库名',
  `read_user` varchar(100) NOT NULL DEFAULT '' COMMENT '读库用户',
  `read_password` varchar(100) NOT NULL DEFAULT '' COMMENT '读库密码',
  `write_host` varchar(100) NOT NULL DEFAULT '' COMMENT '写库地址',
  `write_port` int(11) NOT NULL DEFAULT '3306' COMMENT '写库端口',
  `write_database` varchar(100) NOT NULL DEFAULT '' COMMENT '写库数据库名',
  `write_user` varchar(100) NOT NULL DEFAULT '' COMMENT '写库用户',
  `write_password` varchar(100) NOT NULL DEFAULT '' COMMENT '写库密码',
  `driver` varchar(100) NOT NULL DEFAULT 'mysql' COMMENT '驱动名称',
  `charset` varchar(100) NOT NULL DEFAULT 'utf8' COMMENT '字符集',
  `collation` varchar(100) NOT NULL DEFAULT 'utf8_unicode_ci',
  `prefix` varchar(100) NOT NULL DEFAULT '' COMMENT '数据表前缀',
  `timezone` varchar(100) NOT NULL DEFAULT '+00:00' COMMENT '时区',
  `strict` varchar(10) NOT NULL DEFAULT 'false' COMMENT '是否执行严格模式',
  PRIMARY KEY (`corpid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、创建一个corp_database的model类

class CorpDatabaseModel extends BaseModel{  
  
    private $table = 'corp_database';  
    public function  __construct(){  
        parent::__construct();  
          
    }  
      
    public function  get($corpid){  
      
        if(!$corpid){  
            return null;  
        }  
          
        return app('db')->table($this->table)->where('corpid',$corpid)->first();  
          
    }  
  
    public function  getAndFormat($corpid){  
  
        if(!$corpid){  
            return null;  
        }  
  
        $r = app('db')->table($this->table)->where('corpid',$corpid)->first();  
        if($r) {  
            $result['read']['host'] = $r['read_host'];  
            $result['read']['port'] = $r['read_port'];  
            $result['read']['database'] = $r['read_database'];  
            $result['read']['username'] = $r['read_user'];  
            $result['read']['password'] = $r['read_password'];  
            $result['write']['host'] = $r['write_host'];  
            $result['write']['port'] = $r['write_port'];  
            $result['write']['database'] = $r['write_database'];  
            $result['write']['username'] = $r['write_user'];  
            $result['write']['password'] = $r['write_password'];  
            $result['driver'] = $r['driver'];  
            $result['charset'] = $r['charset'];  
            $result['collation'] = $r['collation'];  
            $result['prefix'] = $r['prefix'];  
            $result['timezone'] = $r['timezone'];  
            $result['strict'] = $r['strict'];  
            return $result;  
        } else {  
            return null;  
        }  
    }  
  
    /** 
     * @param $save_array 
     * @return mixed 
     */  
    public function save($save_array){  
  
        return app('db')->db()->table($this->table)->insertGetId($save_array);  
  
    }  
  
    public function modifyById($id, $data =array()){  
        if(!$id){  
            return 0;  
        }  
        if(!count($data)){  
            return 0;  
        }  
        return app('db')->db()->table($this->table)->where('coprid',$id)->update($data);  
    }  
}  

4、在app/Http/Middleware/xxxMiddleware.php(自行在routes.php中配置生效)中添加以下代码

public function handle($request, Closure $next) {  
        $corpId = $request->get('corpid', '');  
        if($corpId) {  
            $corpDatabaseModel = new CorpDatabaseModel();  
            $dbConfig = $corpDatabaseModel->getAndFormat($corpId);  
            if($dbConfig) {  
                config(['database.connections.' . $corpId => $dbConfig]);  
                config(['database.default' => $corpId]);  
            }  
        }
}  

5、通过中间件修改数据库组件的默认链接名称实现动态分库。这样内部代码不需要做任何特殊处理即可实现对不同数据库分库的访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值