[Magento] 在 .xml 文件中配置模块数据库连接

今天花了点时间研究了一下 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 的配置信息来初始化数据库连接并返回此连接。

Built with Hugo
主题 StackJimmy 设计