Laravel多数据库需先配置再绑定并清缓存,连接名须与config/database.php中完全一致;模型固定绑定用$connection属性,运行时切换用DB::connection()或on()方法;跨库事务不联动,需应用层保障一致性。

在 Laravel 中实现多数据库连接与切换,核心是“先配置、再绑定、按需切换”,不是写个 DB::connection 就能通——连接必须提前注册,名字必须完全一致,缓存必须清掉。
配置多个数据库连接
所有连接都得在 config/database.php 的 connections 数组里显式定义,不能只改 host 或 database 就完事。每个连接必须包含完整字段:
-
driver:必须是
mysql、pgsql等有效值,且对应 PHP 扩展已启用(如pdo_pgsql) -
host / port / database / username / password:全部用
env()包裹,禁止硬编码 -
charset 和 collation:MySQL 8+ 必须配,否则容易报
SQLSTATE[HY000] [2054] - 别动默认的
mysql连接——Laravel 内部功能(如迁移、通知、队列)依赖它
环境变量要用语义化前缀隔离,比如新增日志库就用 DB_LOG_HOST、DB_LOG_DATABASE,而不是复用 DB_HOST。改完 .env 后必须执行:
php artisan config:clear
否则缓存里的旧配置还在生效。
模型级固定绑定连接
适合长期归属某库的模型,比如日志表、租户报表、归档数据等。直接在模型顶部声明:
protected $connection = 'mysql_log';
注意:'mysql_log' 必须和 config/database.php 中 connections 的键名**完全一致**(大小写、下划线都不能错)。设完不清理缓存,这个设置就不生效。也别在构造函数里动态改 $this->connection,它是静态属性,运行时修改无效。
运行时临时切换连接
适合一次请求中需操作多个库,或根据路由参数、用户身份动态选库。有三种常用方式:
-
DB::connection('mysql_second')->table('users')->get():拿到连接实例后必须链式调用查询方法,单独写
DB::connection(...)不会执行任何 SQL -
User::on('mysql_backup')->where(...)->get():Eloquent Builder 方法,仅本次查询生效,会覆盖模型上已设的
$connection - DB::connection()->setConnection('mysql_tenant_123'):慎用,它影响当前连接实例的后续所有操作,但不推荐用于复杂流程,易出错
如果调用时报 Database [xxx] not configured,说明连接名没在 config/database.php 中注册,或者拼写不一致。可用 php artisan tinker 输入 config('database.connections') 查看实际加载了哪些连接。
事务与跨库注意事项
Laravel 的 DB::transaction() 只作用于当前连接实例。如果你在同一个事务里混用 DB::connection('mysql_main') 和 DB::connection('mysql_log'),它们各自提交,不会联动回滚——这会导致数据不一致,而且不会报错。
需要跨库一致性?只能靠应用层处理:比如用 Saga 模式、补偿事务,或把逻辑拆成原子步骤 + 最终一致性校验。不要指望一个 transaction() 包住两个库。


















