今天花了点时间研究了一下 Magento 创建数据库连接的代码,不得不说 Magento 的配置系统的确强大,通过简单的 .xml 配置,就可以实现拆分数据库、读写分离,非常方便,而且日后查看一目了然。
以 Jp_Proposal 模块为例:
具体配置代码如下:
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 | file: app/code/local/Jp/Proposal/etc/config.xml <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 的配置信息来初始化数据库连接并返回此连接。