前面我们学习了如何通过Magento数据模型和ORM系统提供一个简单便捷的方式来获取、存储和操作数据。在进入下面内容的讲解之前,先学习一下Magento数据库适配器以及如何运行SQL查询,但应尽量避免本节中所要学到的内容。因为Magento是一套相应复杂的系统,这个在前面也有提到,这套框架一部分由事件来驱动。仅仅是保存一个产品就会触发不同的事件,由每个事件执行不同的任务。如果通过创建查询语句或直接更新产品则不会用到事件,所以作为开发者,我们需要异常谨慎,确定是否有必要在ORM系统以外进行操作。
虽然这么说,但可直接通过数据库进行操作的实际上要比通过Magento的模型来做也更为简易。比如,在全局更新产品属性或更改产品集合状态,我们可以加载一个产品集合并对每个产品进行遍历以进行更新和保存。这种方法对于小的集合而言没有问题,但在规模上升需要数据较大的数据集时,性能会开始下降,脚本将需要耗时数秒才能完成执行。
然而直接通过SQL语句将会快很多,通常会不到1秒,取决于数据集的大小以及需执行的SQL语句。
Magento会自动通过Mage_Core_Model_Resource模型来建立复杂的数据库连接等问题,连接包含两种类型:core_read和core_write。下面我们来实例化一个资源模型和两个连接,一个读连接一个写连接:
$resource = Mage::getModel('core/resource'); $read = $resource->getConnection('core_read'); $write = $resource->getConnection('core_write');
即使是通过SQL语句直接操作,也可以通过Magento实例化一个资源模型以及对应类型的连接来实现数据库的连接。
读操作
我们通过执行如下代码来测试读连接:
$resource = Mage::getModel('core/resource'); $read = $resource->getConnection('core_read'); $query = 'SELECT * FROM catalog_product_entity'; $results = $read->fetchAll($query);
<尽管上述语句可以运行并返回catalog_product_entity表中的所有产品,但假设我们需要查询安装时添加了前缀的表格呢?或者Magento在下一次更新时修改了表名怎么办?这些代码可移植性不强且不易于维护。幸好资源模型提供了另一个简便的方法getTableName()。
getTableName()方法使用工厂名作为参数,根据config.xml中的配置这个方法可以正确地查找到对应表格,并且会验证表格在数据库中是否存在。下面通过getTableName()方法来对代码进行更新:
$resource = Mage::getModel('core/resource'); $read = $resource->getConnection('core_read'); $query = 'SELECT * FROM ' . $resource->getTableName('catalog/product'); $results = $read->fetchAll($query);
这里我们还用到了fetchAll()方法,这将返回将查询结果的所有行返回为一个数组,但这并不是唯一的方式;我们还可以使用fetchCol()和fetchOne()方法,下面我们就来分析一下这些方法:
- fetchAll:此方法返回从原查询语句中返回的所有行
- fetchOne:该函数仅返回查询语句返回的第一行数据库值
- fetchCol:本方法返回所有行,但仅包含每行的第一列内容,这对于只想获取产品ID或SKU等情况较为有用
写操作
前面已经提到,在Magento中保存模型,不管是产品、分类、客户还是其它的模型,都会导致速度相对较慢,因为在后台中会触发一定数量的observer和事件。
不过假如我们只想更新简单的静态数值,那么通过Magento CRM来更新大量集合实际上是很缓慢的。例如我们想要将站点中的所有产品置为OOS,则无需通过在Magento后台或创建一个脚本在所有产品中进行迭代循环来实现,只需通过如下代码段来轻松实现:
$resource = Mage::getModel('core/resource'); $read = $resource->getConnection('core_write); $tablename = $resource->getTableName('cataloginventory/stock_status'); $query = 'UPDATE {$tablename} SET <code>is_in_stock</code> = 1'; $write->query($query);
下一节我们将开如学习Magento前台开发的相关知识。