系统学习magento二次开发,推荐小册:《Magento中文全栈二次开发 》
本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。
大多数时候,使用Magento,单个数据库连接就足够了。
Magento具有出色的系统,可以在数据库中添加新表或扩展现有表。
那么,为什么需要在Magento系统之外建立外部数据库连接呢?嗯,一个例子是从另一个电子商务系统进行数据迁移。
在本文中,通过 CRUD(创建、读取、更新、删除)示例介绍了与外部数据库的简单连接。
### 配置
此外部数据库连接同样被定义为Magento默认连接 - 在XML配置中。不同之处在于外部连接是在特定模块的 XML 配置中定义的。它定义读取和写入适配器、设置和数据库凭据信息。外部表的定义方式与 magento 表相同。它们位于inchoo_foreignconnection_resource节点下,因此稍后可以在代码中调用模型资源。出于演示目的,XML 配置中有一个前端节点,用于定义控制器 (fconn) 的前端名称。
<?xml version="1.0"?> <config> <modules> <Inchoo_ForeignConnection> <version>1.4.2</version> </Inchoo_ForeignConnection> </modules> <global> <models> <inchoo_foreignconnection> <class>Inchoo_ForeignConnection_Model</class> <resourceModel>inchoo_foreignconnection_resource</resourceModel> </inchoo_foreignconnection> <inchoo_foreignconnection_resource> <class>Inchoo_ForeignConnection_Model_Resource</class> <entities> <product> <table>product_description</table> </product> </entities> </inchoo_foreignconnection_resource> </models> <resources> <inchoo_foreignconnection_write> <connection> <use>inchoo_foreignconnection_database</use> </connection> </inchoo_foreignconnection_write> <inchoo_foreignconnection_read> <connection> <use>inchoo_foreignconnection_database</use> </connection> </inchoo_foreignconnection_read> <inchoo_foreignconnection_setup> <connection> <use>core_setup</use> </connection> </inchoo_foreignconnection_setup> <inchoo_foreignconnection_database> <connection> <host><![CDATA[localhost]]></host> <username><![CDATA[username]]></username> <password><![CDATA[password]]></password> <dbname><![CDATA[db_name]]></dbname> <initStatements><![CDATA[SET NAMES utf8]]></initStatements> <model><![CDATA[mysql4]]></model> <type><![CDATA[pdo_mysql]]></type> <pdo_type><![CDATA[]]></pdo_type> <active>1</active> </connection> </inchoo_foreignconnection_database> </resources> </global> <frontend> <routers> <inchoo_foreignconnection> <use>standard</use> <args> <module>Inchoo_ForeignConnection</module> <frontName>fconn</frontName> </args> </inchoo_foreignconnection> </routers> </frontend> </config>
### 模型
接下来是一个模型,该模型将使用定义的外部连接来获取数据或将数据保存在外部数据库中。在这里,模型使用 XML 配置中的产品表进行初始化,在本例中定义product_description表。
class Inchoo_ForeignConnection_Model_Product extends Mage_Core_Model_Abstract { protected $_eventPrefix = 'inchoo_foreignconnection_product'; protected $_eventObject = 'product'; protected function _construct() { $this->_init('inchoo_foreignconnection/product'); } }
模型资源类也是使用 _init() 函数中相同的 xml 配置节点定义的,但使用 TABLE_PRIMARY_KEY 参数。在此类中,可以创建多个将处理外部数据的函数。
第一个例子是createDataInResource函数,它将数据插入模型的表中。它需要将插入的参数数组。
第二个示例是 readDataFromResource 函数,它从模型的表中获取所有数据。必须先定义读取适配器。它是来自 xml 的配置节点,用于定义读取连接。读取适配器定义后,可以使用Magento数据库函数(select(),from(),limit()等)。当查询完全构造时,可以使用读取适配器执行它。可以使用 fetchPairs() 或 fetchAll() 函数检索数据。fetchAll() 用于获取从 mysql 返回的所有记录。
updateDataInResource 和 deleteDataFromResource 函数采用额外的$id参数,用于定义将更新或删除的记录。
class Inchoo_ForeignConnection_Model_Resource_Product extends Mage_Core_Model_Resource_Db_Abstract { const TABLE_PRIMARY_KEY = 'product_id'; protected function _construct() { $this->_init('inchoo_foreignconnection/product', self::TABLE_PRIMARY_KEY); } public function createDataInResource($values = array()) { $writeAdapter = $this->_getWriteAdapter(); try { $writeAdapter->insert( $this->getMainTable(), $values ); } catch (Exception $e) { Mage::log('Unable to insert data to external resource. ' . $e->getMessage(), null, null, true); } } public function readDataFromResource() { $data = array(); $readAdapter = $this->_getReadAdapter(); $select = $readAdapter->select() ->from($this->getMainTable(), '*') ->limit(20); try { $data = $readAdapter->fetchAll($select); } catch (Exception $e) { Mage::log('Unable to fetch data from external resource. ' . $e->getMessage(), null, null, true); } return $data; } public function updateDataInResource($id, $values = array()) { $writeAdapter = $this->_getWriteAdapter(); try { $writeAdapter->update( $this->getMainTable(), $values, self::TABLE_PRIMARY_KEY . '=' . $id ); } catch (Exception $e) { Mage::log('Unable to update data in external resource. ' . $e->getMessage(), null, null, true); } } public function deleteDataFromResource($id) { $writeAdapter = $this->_getWriteAdapter(); try { $writeAdapter->delete( $this->getMainTable(), self::TABLE_PRIMARY_KEY . '=' . $id ); } catch (Exception $e) { Mage::log('Unable to delete data from external resource. ' . $e->getMessage(), null, null, true); } } } class Inchoo_ForeignConnection_Model_Resource_Product_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { public function _construct() { $this->_init('inchoo_foreignconnection/product'); } }
### 控制器中的用法
所有这些函数都在 IndexController 类中演示,但由于它们是在模型的资源类中定义的,因此可以在任何控制器类中调用它们。
class Inchoo_ForeignConnection_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { // Create $foreignProductCreate = Mage::getModel('inchoo_foreignconnection/product')->getResource(); $foreignProductCreate->createDataInResource( array( 'product_name' => 'Product name', 'product_description' => 'Product description' ) ); // Read $foreignProductRead = Mage::getModel('inchoo_foreignconnection/product')->getResource(); $result = $foreignProductRead->readDataFromResource(); var_dump($result); // Update $foreignProductUpdate = Mage::getModel('inchoo_foreignconnection/product')->getResource(); $foreignProductUpdate->updateDataInResource( 3394, array( 'product_name' => 'Product name updated', 'product_description' => 'Product description updated' ) ); // Delete $foreignProductDelete = Mage::getModel('inchoo_foreignconnection/product')->getResource(); $foreignProductDelete->deleteDataFromResource(3394); } }
在大多数情况下,Magento将使用不同类型的外部连接来检索或发送数据,但有时像这样的外部数据库连接将是最好的方法。
其中一个例子是,当您想使用他们的xsell或追加销售产品将产品从另一个系统导入Magento时。
在这种情况下,读取连接将用于检索产品数据,写入连接将用于将xsell或追加销售产品ID保存在临时表中,以便在导入来自外部系统的所有产品时可以将它们分配给Magento产品。