CodeIgniter 4 中模型临时切换数据库需显式创建独立连接实例,禁用 $this->db 赋值和 CI3 风格 DB();推荐用 Config\Database::connect('group_name') 获取新实例,或构造函数注入复用;多库须禁用持久连接以防事务污染。

在 CodeIgniter 4 模型中临时切换数据库连接组,不能依赖 $this->db(它始终指向默认库),也不能用 CI3 风格的 DB('group_name') —— CI4 已移除该函数。核心原则是:**模型本身不绑定特定连接,需显式创建并使用独立的数据库实例**。
直接用 Config\Database::connect() 获取指定组连接
这是最常用、最安全的方式。在模型方法内部按需调用,返回一个全新的 ConnectionInterface 实例,与当前模型的 $this->db 完全无关:
- 确保目标数据库组已在
app/Config/Database.php中正确定义(如$db['log_db']) - 在模型方法里调用:
$logDb = \Config\Database::connect('log_db'); - 后续所有查询都基于该实例:
$logDb->table('logs')->insert($data); - 无需手动关闭连接,CI4 连接池会自动管理生命周期
把连接实例注入模型构造函数(适合高频复用)
若某个模型长期需要操作非默认库(例如 LogModel 总是写入日志库),可在构造时传入连接对象,避免每次重复调用 connect:
- 定义模型时接收参数:
public function __construct(ConnectionInterface $logDb = null) - 在控制器中初始化:
$logModel = new LogModel(\Config\Database::connect('log_db')); - 模型内保存为属性:
$this->logDb = $logDb ?? \Config\Database::connect('default'); - 后续方法统一使用
$this->logDb,逻辑清晰且可测试
注意事务与连接隔离问题
多个连接组若共用同一 MySQL 主机+端口+用户,默认可能复用底层连接资源,导致事务错乱(比如在 A 库 start_transaction 后,commit 却发到 B 库):
- 必须在
app/Config/Database.php的每个数据库组配置中显式设置'pconnect' => false - 即使你希望复用连接,多库场景下也必须关掉持久连接,否则事务和字符集等状态容易污染
- 不同连接组之间事务完全独立,无法跨库提交或回滚
别误用 $this->db 或试图“切换”它
模型中的 $this->db 是框架初始化时绑定的默认连接,不可重赋值或动态替换:
-
$this->db = \Config\Database::connect('other_db');是无效的,会导致后续 Query Builder 方法异常 - 也不要在模型里调用
Services::database(),它返回的是默认连接服务,不接受组名参数 - 所有“临时切换”都必须走新实例 + 显式调用路径,不改变模型原有 db 属性











