今天花了点时间研究了一下 Magento 创建数据库连接的代码,不得不说 Magento 的配置系统的确强大,通过简单的 .xml 配置,就可以实现拆分数据库、读写分离,非常方便,而且日后查看一目了然。
以 Jp_Proposal 模块为例:
具体配置代码如下:
文件路径:
app/code/local/Jp/Proposal/etc/config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<resources>
<jp_proposal_setup>
<setup>
<module>Jp_Proposal</module>
</setup>
<connection>
<host>localhost</host>
<username>username</username>
<password>password</password>
<dbname>database_name</dbname>
<model>mysql4</model>
<initStatements>SET NAMES utf8</initStatements>
<type>pdo_mysql</type>
<active>1</active>
</connection>
</jp_proposal_setup>
<jp_proposal_read>
<connection>
<host>localhost</host>
<username>username</username>
<password>password</password>
<dbname>database_name</dbname>
<model>mysql4</model>
<initStatements>SET NAMES utf8</initStatements>
<type>pdo_mysql</type>
<active>1</active>
</connection>
</jp_proposal_read>
<jp_proposal_write>
<connection>
<host>localhost</host>
<username>username</username>
<password>password</password>
<dbname>database_name</dbname>
<model>mysql4</model>
<initStatements>SET NAMES utf8</initStatements>
<type>pdo_mysql</type>
<active>1</active>
</connection>
</jp_proposal_write>
</resources>
|
通过以上简单配置,Jp_Proposal 模块的 setup, read, write 三种数据库连接都会以上面的配置信息初始化,达到分库、读写分离的目的。
Magento 中生成数据库连接的代码位于 Resource 的基类: Mage_Core_Model_Resource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
/**
* Creates a connection to resource whenever needed
*
* @param string $name
* @return Varien_Db_Adapter_Interface
*/
public function getConnection($name)
{
if (isset($this->_connections[$name])) {
$connection = $this->_connections[$name];
if (isset($this->_skippedConnections[$name]) && !Mage::app()->getIsCacheLocked()) {
$connection->setCacheAdapter(Mage::app()->getCache());
unset($this->_skippedConnections[$name]);
}
return $connection;
}
$connConfig = Mage::getConfig()->getResourceConnectionConfig($name);
if (!$connConfig) {
$this->_connections[$name] = $this->_getDefaultConnection($name);
return $this->_connections[$name];
}
if (!$connConfig->is('active', 1)) {
return false;
}
$origName = $connConfig->getParent()->getName();
if (isset($this->_connections[$origName])) {
$this->_connections[$name] = $this->_connections[$origName];
return $this->_connections[$origName];
}
$connection = $this->_newConnection((string)$connConfig->type, $connConfig);
if ($connection) {
if (Mage::app()->getIsCacheLocked()) {
$this->_skippedConnections[$name] = true;
} else {
$connection->setCacheAdapter(Mage::app()->getCache());
}
}
$this->_connections[$name] = $connection;
if ($origName !== $name) {
$this->_connections[$origName] = $connection;
}
return $connection;
}
|
在上面代码中,以 Jp_Proposap 模块 read 为例, $name = “jp_proposal_read”。
在初始化数据库连接时,先去配置文件里面查找 global -> resources -> jp_proposal_read 节点,如果可以找到这个节点,就以其中的配置信息初始化数据库连接并返回此数据库连接; 如果没有找到这个节点(节点不存在),则使用 Magento 默认的 core_read 的配置信息来初始化数据库连接并返回此连接。