深入理解CI框架:数据库的加载过程
说明:没特别指明的情况下,本文涉及的Codeigniter均为3.1.2版。
要在 CI 框架里使用数据库,你可以显示地加载它:
1 | $this->load->database(db_to_load); |
也可以在加载 model 的时候顺带加载数据库:
1 | // 第三个参数 |
当我们只有一个数据库的时候,上面两种方法都行得通。默认情况下,CI 把数据库连接赋值给一个叫 db 的属性。但如果有多个数据库(>=2),并且要经常切换,就只能使用 database()
并且第二个参数传 true,例如:
1 | $this->dblink = $this->load->database(db_to_load, true);//return ? |
我们看一下 database()
方法的部分实现细节:
1 | // database() 方法开头会判断 db 是否已被赋值 |
看得出来,每次执行 database(db_to_load, true) 的时候都会连接一次数据库,所以在必要时才 load model。
注:1. 上面指的是调用 database(db_to_load, true);不是 database(db_to_load);
2. 读者事先看过 DB() 方法,知道 DB() 会去连数据库 o( ̄▽ ̄)o 。
下面是 DB()
方法的部分实现细节:
1 | ... |
下面是 initialize()
方法的部分实现细节:
1 | /* |
如果你再深入源码了解 CI_DB_driver 类,你会发现下面的关系链:
$driver extends CI_DB { } // drivers 举例: CI_DB_mysql_driver
class CI_DB extends CI_DB_query_builder { } // CI_DB 是个空类
// or: class CI_DB extends CI_DB_driver { }
abstract class CI_DB_query_builder extends CI_DB_driver { }
abstract class CI_DB_driver { }
上面出现了两个抽象类,它们一个偏向于 Query,一个偏向于 DB,下面是两个类的注释:
CI_DB_query_builder : This is the platform-independent base Query Builder implementation class.
CI_DB_driver: This is the platform-independent base DB implementation class.
CI_DB
是个空类,没有任何实现,但是所有数据库驱动类(例如 CI_DB_mysql_driver
)都继承 CI_DB
。
注意到 &DB(params, query_builder_override)
方法的第二个参数,它决定了 CI_DB
继承 CI_DB_query_builder
还是 CI_DB_driver
:
1 | if (! isset($query_builder) OR $query_builder === TRUE) |
可以看出来,CI_DB
起到了“适配器”的作用。
完。