Hyperf模型切换数据库连接需区分静态绑定与运行时指定:静态绑定通过模型$connection属性固定连接,适用于业务域划分场景;运行时用Db::connection()临时切换,适合单次跨库操作;多租户需中间件注册连接并动态注入;Swow环境下须重配连接池参数并重启服务。

Hyperf 模型切换数据库连接,核心在于明确“静态绑定”和“运行时指定”两种方式的适用场景与写法差异。模型类本身不自动感知请求上下文变化,所以不能靠改配置文件就让模型动态换库——必须在代码中显式控制。
模型类内固定指定 connection
适合连接关系稳定、按业务域划分的场景,比如日志库、报表库、主从分离等。
- 在模型类顶部声明 $connection 属性,值为
config/autoload/databases.php中connections数组的键名,例如:protected $connection = 'log_db'; - 该设置仅在类加载时读取一次,后续不会随配置变更而更新
- 所有静态方法(
find、all)、实例方法(save、delete)及关联查询(with)都走这个连接,但关联模型仍使用自身定义的$connection,不会继承父模型
运行时用 Db::connection() 临时切换
适合单次跨库操作,如后台导出、数据迁移、混合查询,不改变模型默认行为。
- 直接调用
Db::connection('report_db')->table('sales')->where(...)->get() - 支持 Query Builder 和 Eloquent 查询构造器链式调用,事务也一样:
Db::connection('report_db')->transaction(...) - 注意:不能混用
Db::table()或模型静态方法,它们始终走默认连接;Db::connection()返回的是全新 Query 实例,与全局 Db 独立 - 连接名大小写敏感,拼错会抛出
Connection not found
多租户场景下动态注入 connection
租户 ID 来自子域名、请求头或 JWT payload 时,需在请求生命周期早期完成连接注册与模型适配。
- 在中间件中解析租户标识(如
tenant-a),组装数据库配置数组,调用Db::setConnectConfig('tenant_a', $config)注册连接 - 将租户 ID 绑定到 Request 对象或上下文(
Context::set()),供后续模型读取 - 可创建 BaseModel,在
__callStatic中拦截find、create等调用,检查租户 ID 并自动追加->connection('tenant_' . $id) -
Db::setConnectConfig是幂等的,重复注册同名连接不会刷新已有连接对象;若租户密码变更,需先Db::closeConnect('tenant_a')再重注册
Swow 环境下的特别注意
启用 Swow 协程引擎后,数据库连接池参数必须重配,否则连接泄漏、idle 不回收、pool exhausted 等问题频发。
- 删除原
databases.php中所有旧版pool配置项,改用 Swow 专用结构 - MySQL 配置块内新增
'pool' => ['min_connections' => 8, 'max_connections' => 64, 'check_interval' => 3000],其中check_interval不得低于 3000 毫秒 - 修改后必须清空
runtime/container并重启服务,否则旧 Pool 实例残留导致新配置不生效


















