CodeIgniter多数据库前缀:如何在Query Builder中使用多前缀?
好问题!在CodeIgniter里处理多数据库前缀的需求,完全不用退而求其次用原生SQL,有几种很优雅的方案可以继续用Query Builder,我给你详细说说:
方案1:配置多个数据库连接(最推荐)
这是最贴合CodeIgniter设计思路的方法——给不同前缀的表组配置独立的数据库连接,每个连接自带对应的前缀,这样Query Builder会自动为对应连接的表加上前缀。
步骤1:修改数据库配置文件
打开application/config/database.php,在原有默认连接的基础上,新增两个连接配置:
$db['default'] = array( 'hostname' => DB_HOST, 'username' => DB_USER, 'password' => DB_PASS, 'database' => DB_NAME, 'dbdriver' => 'mysqli', 'dbprefix' => 'mci_' ); $db['dept'] = array( 'hostname' => DB_HOST, 'username' => DB_USER, 'password' => DB_PASS, 'database' => DB_NAME, 'dbdriver' => 'mysqli', 'dbprefix' => 'mdept_' ); $db['ext'] = array( 'hostname' => DB_HOST, 'username' => DB_USER, 'password' => DB_PASS, 'database' => DB_NAME, 'dbdriver' => 'mysqli', 'dbprefix' => 'mext_' );
(注意:三个连接用的是同一个数据库,只是前缀不同)
步骤2:在代码中使用对应连接
在控制器或模型里,你可以加载不同的连接来操作对应前缀的表:
// 使用默认连接操作mci_前缀的表 $this->db->select('*')->from('users')->get(); // 实际查询 `mci_users` // 加载部门表连接,操作mdept_前缀的表 $dept_db = $this->load->database('dept', TRUE); $dept_db->select('name')->from('departments')->where('id', 5)->get(); // 实际查询 `mdept_departments` // 加载外部数据表连接,操作mext_前缀的表 $ext_db = $this->load->database('ext', TRUE); $ext_db->insert('external_data', array('content' => 'test')); // 实际插入到 `mext_external_data`
这种方法的优势是完全利用CI原生的Query Builder功能,不需要额外封装,代码逻辑清晰,不容易出错。
方案2:封装辅助函数快速生成带前缀的表名
如果你不想维护多个数据库连接,可以写一个简单的辅助函数,用来拼接前缀和表名,这样在Query Builder里直接使用拼接后的表名即可。
步骤1:创建辅助函数
在application/helpers/目录下新建db_prefix_helper.php,内容如下:
if (!function_exists('prefix_table')) { /** * 生成带指定前缀的表名 * @param string $table 原始表名 * @param string $prefix 目标前缀 * @return string 带前缀的表名 */ function prefix_table($table, $prefix) { return $prefix . $table; } }
步骤2:使用辅助函数
在需要的地方先加载辅助函数,然后调用:
// 加载辅助函数 $this->load->helper('db_prefix'); // 查询mdept_departments表 $this->db->get(prefix_table('departments', 'mdept_')); // 查询mext_external_data表并添加条件 $this->db->where('status', 1)->get(prefix_table('external_data', 'mext_'));
这个方案比较轻量,适合偶尔需要切换前缀的场景,不用额外管理数据库连接。
方案3:扩展Query Builder添加自定义方法
如果你想让语法更贴合Query Builder的风格,可以扩展CI的Query Builder类,添加支持指定前缀的方法。
步骤1:创建扩展类
在application/core/目录下新建MY_DB_query_builder.php(注意:类名前缀要和你在config.php里设置的$config['subclass_prefix']一致,默认是MY_):
class MY_DB_query_builder extends CI_DB_query_builder { /** * 指定带前缀的表作为查询来源 * @param string $table 原始表名 * @param string $prefix 目标前缀 * @return $this */ public function from_prefix($table, $prefix) { return $this->from($prefix . $table); } /** * 直接查询带指定前缀的表 * @param string $table 原始表名 * @param string $prefix 目标前缀 * @param int|null $limit 条数限制 * @param int|null $offset 偏移量 * @return CI_DB_result */ public function get_prefix($table, $prefix, $limit = NULL, $offset = NULL) { return $this->get($prefix . $table, $limit, $offset); } }
步骤2:使用自定义方法
现在你可以像用原生Query Builder方法一样调用这些自定义方法:
// 查询mdept_departments表 $this->db->select('id, name')->from_prefix('departments', 'mdept_')->get(); // 直接查询mext_external_data表并限制条数 $this->db->get_prefix('external_data', 'mext_', 10);
这个方案让代码风格更统一,适合频繁使用多前缀表的场景。
内容的提问来源于stack exchange,提问作者Anupam

