ThinkPHP6 如何配置多数据库连接并切换?

文章导读
ThinkPHP6 配置多数据库连接需在 config/database.php 的 connections 数组中预定义完整配置,切换连接必须通过 Db::connect('连接名') 显式调用或在模型中声明 protected $connection 属性。此方案适用于多租户、读写分离及日志库隔离场景,但需注意事务不支持跨连接提交。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

ThinkPHP6 配置多数据库连接需在 config/database.php 的 connections 数组中预定义完整配置,切换连接必须通过 Db::connect('连接名') 显式调用或在模型中声明 protected $connection 属性。此方案适用于多租户、读写分离及日志库隔离场景,但需注意事务不支持跨连接提交。

先说结论:ThinkPHP6 多数据库配置依赖预定义连接池,运行时切换需显式指定连接标识,模型绑定仅初始化生效。

  • 适合:多租户隔离、读写分离、独立日志库场景
  • 先看:config/database.php 中 connections 键名必须为小写字母加下划线
  • 建议:跨库操作避免使用事务,动态连接需配合 Db::setConnectConfig 注册

命令速用版

多数据库配置无需命令行,直接修改配置文件并调用指定方法即可生效。

配置文件修改:在 config/database.php 的 connections 数组中添加新连接。

'connections' => [
    'mysql' => [...],
    'slave_db' => [
        'type' => 'mysql',
        'hostname' => '192.168.1.100',
        'database' => 'db_slave',
        'username' => 'root',
        'password' => 'password',
    ],
]

代码切换连接:使用 Db::connect 指定连接名。

$list = Db::connect('slave_db')->table('user')->select();

为什么会这样

ThinkPHP6 的 Db::connect 方法创建的是独立连接实例,不会修改全局默认连接状态。

框架设计基于连接池机制,默认连接在首次数据库操作时初始化并缓存。直接调用 Db::connect 返回新对象,若未赋值或链式调用,该对象会被丢弃,后续操作仍走默认库。模型类的 $connection 属性仅在类初始化时读取一次,运行时修改配置不会自动刷新已加载的模型连接。

分步处理

第一步:定义连接配置

打开 config/database.php,在 connections 数组中定义新连接。键名仅支持小写字母和下划线,不可包含点号或大写字母。确保 type、hostname、database、username、password 参数齐全,缺少 type 会导致驱动加载失败。

第二步:选择切换方式

ThinkPHP6 如何配置多数据库连接并切换?

临时查询使用 Db::connect('连接名')->table('表名')->select(),必须链式调用或赋值给变量。固定模型连接需在模型类中声明 protected $connection = '连接名',该设置对 find、save 等操作生效。

第三步:动态注册连接(多租户场景)

若连接参数运行时确定,先在中间件调用 Db::setConnectConfig('标识', $配置数组) 注册,再通过 Db::connect('标识') 使用。避免在控制器循环中反复注册,建议配合缓存减少配置计算。

怎么验证是否生效

执行查询后打印连接配置确认数据库名。使用 dump(Db::connect('连接名')->getConfig()['database']) 查看当前连接指向的数据库名称。对比不同连接实例的 getConfig 返回值,确保分别指向预期库。检查业务数据是否写入正确数据库,避免因前缀配置错误导致表名拼接异常。

常见坑

连接名大小写敏感,'User' 与 'user' 视为不同连接,写错会报 Connection not found。事务不支持跨连接,Db::connect('a')->startTrans() 与 Db::connect('b')->startTrans() 无法合并提交。模型关联查询默认走各自模型配置的连接,不会继承主模型连接,跨库关联需手动分查。env 文件无法定义多维 connections 配置,多库必须写死在 database.php 中。

常见问题

Db::connect 后为什么还是查的默认库?

因为 Db::connect 返回新实例未保存,后续 Db::table 仍走全局默认连接。必须链式调用或赋值变量。

模型如何固定使用非默认数据库?

在模型类顶部添加 protected $connection = '连接名' 属性,值需与配置文件键名一致。

多数据库之间能开启事务吗?

不能。事务绑定在单个 PDO 实例上,不同连接标识视为独立事务,无法回滚。

动态切换连接配置怎么写?

先用 Db::setConnectConfig 注册配置数组,再用 Db::connect 调用注册的标识。

参考来源

  • ThinkPHP6 如何配置多数据库连接_ThinkPHP6 配置多数据库连接【复杂】
  • ThinkPHP6 怎么配置多数据库连接?_ThinkPHP6 多库连接与读写分离【架构】
  • ThinkPHP6 如何切换数据库连接?_ThinkPHP6 动态切换 Db 连接实战【技巧】
  • ThinkPHP6.0 多数据库连接_ThinkPHP6.0 切换数据库连接方法【数据库】
  • ThinkPHP 如何配置多个数据库连接_ThinkPHP 跨库操作教程【教程】