Hyperf通过配置多个数据库连接名实现多库支持,运行时用Db::connection('name')切换,Eloquent模型可设$connection属性,注解方式需谨慎使用,跨库JOIN不支持。

Hyperf 支持多数据库连接,核心在于配置多个数据源,并通过 Db 组件的连接名(connection name)进行切换。不是靠手动改配置文件来“切换”,而是运行时指定连接名或使用注解/上下文绑定。
一、配置多个数据库连接
在 config/autoload/databases.php 中定义多个连接,每个连接需有唯一 name:
'connections' => [
'default' => [
'driver' => env('DB_DRIVER', 'mysql'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'hyperf'),
// ... 其他字段
],
'log_db' => [
'driver' => 'mysql',
'host' => '192.168.1.100',
'port' => 3306,
'database' => 'log_center',
'username' => 'log_user',
'password' => 'xxx',
],
'report_db' => [
'driver' => 'pgsql',
'host' => 'pg-report.internal',
'database' => 'reports',
'username' => 'rep_user',
// ...
],
],
注意:default 是默认连接名,不显式指定时自动使用它。
二、运行时指定连接名操作数据
所有 Db 操作都可通过 connection() 方法切换连接:
- 查询:
Db::connection('log_db')->table('logs')->where('level', 'error')->get(); - 事务:
Db::connection('report_db')->transaction(function () { ... }); - Query Builder / Eloquent 都支持该方式
如果是 Eloquent 模型,可在模型类中指定 $connection 属性:
class LogRecord extends Model
{
protected $connection = 'log_db';
}
三、用注解自动绑定连接(推荐用于服务层)
配合 hyperf/database 和 hyperf/aop,可自定义注解实现方法级连接切换:
- 定义注解
@DbConnection("log_db") - 写一个 Aspect,在方法执行前调用
Db::setDefaultConnection($name) - 注意:此方式影响的是当前协程内
Db::的默认连接,适合简单场景 - 更安全的做法仍是显式调用
connection(),避免隐式状态污染
四、跨库关联与注意事项
Hyperf 的 Db 不支持跨连接的 JOIN 查询(底层是不同 PDO 实例)。如需关联多库数据:
- 分步查:先查主库 ID 列表,再用 IN 查询从库;或用 Collection 合并
- 避免在事务中混用多个连接(MySQL 不支持跨实例 XA 事务)
- 连接名拼写错误会导致 fallback 到 default 或报错,建议封装工具函数校验
连接池、读写分离等高级能力,也基于同一套 connection 配置扩展,只需增加 read/write 子配置即可。










