Magento中直接使用SQL语句

原理:

 

magento是基于Zend Framework的,所以底层用的还是zend的zend db

 

在文件app/code/core/Mage/Catalog/model/Resource/Eav /Mysql4/Config.php 中追踪到下面的函数 getAttributesUsedInListing()

Php代码 复制代码   收藏代码
  1. /**  
  2. * Retrieve Product Attributes Used in Catalog Product listing  
  3. *  
  4. * @return array  
  5. */  
  6. public function getAttributesUsedInListing() {   
  7. $select = $this->_getReadAdapter()->select()   
  8. ->from(array(’main_table’ => $this->getTable(’eav/attribute’)))   
  9. ->join(   
  10. array(’additional_table’ => $this->getTable(’catalog/eav_attribute’)),   
  11. ‘main_table.attribute_id = additional_table.attribute_id’,   
  12. array()   
  13. )   
  14. ->joinLeft(   
  15. array(’al’ => $this->getTable(’eav/attribute_label’)),   
  16. ‘al.attribute_id = main_table.attribute_id AND al.store_id = ‘ . (int) $this->getStoreId(),   
  17. array(’store_label’ => new Zend_Db_Expr(’IFNULL(al.value, main_table.frontend_label)’))   
  18. )   
  19. ->where(’main_table.entity_type_id=?’, $this->getEntityTypeId())   
  20. ->where(’additional_table.used_in_product_listing=?’, 1);   
  21. – $sql = $select->assemble();   
  22. – echo $sql;   
  23. return $this->_getReadAdapter()->fetchAll($select);   
  24. }  
/**
* Retrieve Product Attributes Used in Catalog Product listing
*
* @return array
*/
public function getAttributesUsedInListing() {
$select = $this->_getReadAdapter()->select()
->from(array(’main_table’ => $this->getTable(’eav/attribute’)))
->join(
array(’additional_table’ => $this->getTable(’catalog/eav_attribute’)),
‘main_table.attribute_id = additional_table.attribute_id’,
array()
)
->joinLeft(
array(’al’ => $this->getTable(’eav/attribute_label’)),
‘al.attribute_id = main_table.attribute_id AND al.store_id = ‘ . (int) $this->getStoreId(),
array(’store_label’ => new Zend_Db_Expr(’IFNULL(al.value, main_table.frontend_label)’))
)
->where(’main_table.entity_type_id=?’, $this->getEntityTypeId())
->where(’additional_table.used_in_product_listing=?’, 1);
– $sql = $select->assemble();
– echo $sql;
return $this->_getReadAdapter()->fetchAll($select);
}
 

Magento操作数据库是在 Zend DB(Zend Framework)的基础上简单的做了下封装了。Zend DB 有自己的一套规则,来组合生成最终的SQL查询语句,可以看到上面的代码中有 from() join() joinLeft() where() 等函数,乱七八糟的一大堆东西,需要对 Zend DB的规则非常熟悉,才能知道实际执行的SQL语句,有没有办法直接打印出SQL语句?找了下,还真有,就是assemble()函数。在上面代码中最后 部分可以看到。顺被把SQL也附上来

Sql代码 复制代码   收藏代码
  1. SELECT `main_table`.*,   
  2. IFNULL(al.value, main_table.frontend_label) AS `store_label`   
  3. FROM `eav_attribute` AS `main_table`   
  4. INNER JOIN `catalog_eav_attribute` AS `additional_table`   
  5. ON main_table.attribute_id = additional_table.attribute_id   
  6. LEFT JOIN `eav_attribute_label` AS `al`   
  7. ON al.attribute_id = main_table.attribute_id AND al.store_id = 1   
  8. WHERE (main_table.entity_type_id=’4′)   
  9. AND (additional_table.used_in_product_listing=1)  
SELECT `main_table`.*,
IFNULL(al.value, main_table.frontend_label) AS `store_label`
FROM `eav_attribute` AS `main_table`
INNER JOIN `catalog_eav_attribute` AS `additional_table`
ON main_table.attribute_id = additional_table.attribute_id
LEFT JOIN `eav_attribute_label` AS `al`
ON al.attribute_id = main_table.attribute_id AND al.store_id = 1
WHERE (main_table.entity_type_id=’4′)
AND (additional_table.used_in_product_listing=1)

 

Magento中打印SQL语句来调试

 

有时为了调试magento商城系统,需要获取当前的查询sql语句,magento中获取SQL语句,这里我们通过


$collection->getSelectSql(true)来调试sql

Php代码 复制代码   收藏代码
  1. $collection=Mage::getResourceModel('reports/product_collection');   
  2. $query=$collection->getSelectSql(true);   
  3. echo $query;  
$collection=Mage::getResourceModel('reports/product_collection');
$query=$collection->getSelectSql(true);
echo $query;
 

magento获取SQL语句的另外一种方法是设置打印SQL为true

Php代码 复制代码   收藏代码
  1. $collection=Mage::getResourceModel('reports/product_collection');   
  2. $collection->printlogquery(true);  
$collection=Mage::getResourceModel('reports/product_collection');
$collection->printlogquery(true);
 

得到的SQL语句

Sql代码 复制代码   收藏代码
  1. SELECT `e`.* FROM `catalog_product_entity` AS `e`  
SELECT `e`.* FROM `catalog_product_entity` AS `e`
 

这里只是打印查询产品的SQL,如果要获取其他地方的SQL语句,道理也是一样的,我们根据上面的sql语句可以看到,其实magento的性能很差,"select *",magetno又是基于EAV架构的,可以想象下这速度

 

操作:

 

Magento的Models 和Collection 很强大,使用它们可以很方便的查询和操作数据库。但是有些场合,因为一些特殊需求或对Magento的了解不够深,可能会需要自己手写SQL语句来查询和操作数据库。以下分别是读写数据库的代码。

Php代码 复制代码   收藏代码
  1. // For Read   
  2. // fetch read database connection that is used in Mage_Core module   
  3.   
  4. $read= Mage::getSingleton('core/resource')->getConnection('core_read');   
  5.   
  6. // first way   
  7. $query = $read->query("select name from core_website");   
  8. while ($row = $query->fetch())    
  9. {    
  10.     $row = new Varien_Object($row);     
  11.     echo "<strong>" . $row->getName() . "</strong><br/>";   
  12. }   
  13.   
  14. // second way    
  15. $results = $read->fetchAll("SELECT * FROM core_website;");    
  16. foreach ($results as $row)    
  17. {   
  18.     echo $row['name'] . "<br/>";     
  19. }   
// For Read
// fetch read database connection that is used in Mage_Core module

$read= Mage::getSingleton('core/resource')->getConnection('core_read');

// first way
$query = $read->query("select name from core_website");
while ($row = $query->fetch()) 
{ 
	$row = new Varien_Object($row);  
	echo "<strong>" . $row->getName() . "</strong><br/>";
}

// second way 
$results = $read->fetchAll("SELECT * FROM core_website;"); 
foreach ($results as $row) 
{
	echo $row['name'] . "<br/>";  
} 
  
Php代码 复制代码   收藏代码
  1. // For Write   
  2. // fetch write database connection that is used in Mage_Core module   
  3. $write = Mage::getSingleton('core/resource')->getConnection('core_write');   
  4.   
  5. // now $write is an instance of Zend_Db_Adapter_Abstract   
  6. $write->query("insert into tablename values ('aaa','bbb','ccc')");  
// For Write
// fetch write database connection that is used in Mage_Core module
$write = Mage::getSingleton('core/resource')->getConnection('core_write');

// now $write is an instance of Zend_Db_Adapter_Abstract
$write->query("insert into tablename values ('aaa','bbb','ccc')");

 

注意上面的getConnection()方法中的参数 "core_read",表明了Magento将要使用的资源。与之相对应,当我们修改数据库的时候使用参数"core_write".一般情况下 getConnection方法的参数应设成"core_read" 或 "core_write"(应该不指定也是可以的,但是如果Magento有多个数据库就必须指定了)。

 

作为新的entension module,在config.xml对"core_read" "core_write" 进行定义是个好的习惯。定义如下: 

Xml代码 复制代码   收藏代码
  1. <config>  
  2.     <global>  
  3.         <resources>  
  4.             <extension_setup>  
  5.                 <connection>  
  6.                     <use>core_setup</use>  
  7.                 </connection>  
  8.             </extension_setup>  
  9.             <extension_read>  
  10.                 <connection>  
  11.                     <use>core_read</use>  
  12.                 </connection>  
  13.             </extension_read>  
  14.             <extension_write>  
  15.                 <connection>  
  16.                     <use>core_write</use>  
  17.                 </connection>  
  18.             </extension_write>  
  19.         </resources>  
  20.     </global>  
  21. </config>  
 

对应上面新增的module的名字.使用下面相对应的语句在read或write Database:

 

Php代码 复制代码   收藏代码
  1. $conn = Mage::getSingleton('core/resource')->getConnection('extension_read');   
  2. $conn = Mage::getSingleton('core/resource')->getConnection('extension_write');  
$conn = Mage::getSingleton('core/resource')->getConnection('extension_read');
$conn = Mage::getSingleton('core/resource')->getConnection('extension_write');
 

一般情况是绝大多数的module都定义成"core_read" "core_write"方便且节省资源。当然特殊情况除外:

  • 给每个module不同的读写权限
  • 需要用多个Database

实例:

 

Php代码 复制代码   收藏代码
  1. <?php   
  2.     /**  
  3.      * Get the resource model  
  4.      */  
  5.     $resource = Mage::getSingleton('core/resource');   
  6.     
  7.     /**  
  8.      * Retrieve the read connection  
  9.      */  
  10.     $readConnection = $resource->getConnection('core_read');   
  11.     
  12.     /**  
  13.      * Retrieve the write connection  
  14.      */  
  15.     $writeConnection = $resource->getConnection('core_write');  
<?php
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Retrieve the read connection
     */
    $readConnection = $resource->getConnection('core_read');
 
    /**
     * Retrieve the write connection
     */
    $writeConnection = $resource->getConnection('core_write');
  
Get a table name from a string
Php代码 复制代码   收藏代码
  1. <?php   
  2.     
  3.     /**  
  4.      * Get the resource model  
  5.      */  
  6.     $resource = Mage::getSingleton('core/resource');   
  7.     
  8.     /**  
  9.      * Get the table name  
  10.      */  
  11.     $tableName = $resource->getTableName('catalog_product_entity');   
  12.     
  13.     /**  
  14.      * if prefix was 'mage_' then the below statement  
  15.      * would print out mage_catalog_product_entity  
  16.      */  
  17.     echo $tableName;  
<?php
 
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Get the table name
     */
    $tableName = $resource->getTableName('catalog_product_entity');
 
    /**
     * if prefix was 'mage_' then the below statement
     * would print out mage_catalog_product_entity
     */
    echo $tableName;
  
Get a table name from an entity name
Php代码 复制代码   收藏代码
  1. <?php   
  2.     
  3.     /**  
  4.      * Get the resource model  
  5.      */  
  6.     $resource = Mage::getSingleton('core/resource');   
  7.     
  8.     /**  
  9.      * Get the table name  
  10.      */  
  11.     $tableName = $resource->getTableName('catalog/product');   
  12.     
  13.     /**  
  14.      * if prefix was 'mage_' then the below statement  
  15.      * would print out mage_catalog_product_entity  
  16.      */  
  17.     echo $tableName;  
<?php
 
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Get the table name
     */
    $tableName = $resource->getTableName('catalog/product');
 
    /**
     * if prefix was 'mage_' then the below statement
     * would print out mage_catalog_product_entity
     */
    echo $tableName;
  

Reading From The Database

 

Varien_Db_Select::fetchAll

This method takes a query as it's parameter, executes it and then returns all of the results as an array. In the code example below, we use Varien_Db_Select::fetchAll to return all of the records in the catalog_product_entity table.

Php代码 复制代码   收藏代码
  1. <?php   
  2.     
  3.     /**  
  4.      * Get the resource model  
  5.      */  
  6.     $resource = Mage::getSingleton('core/resource');   
  7.     
  8.     /**  
  9.      * Retrieve the read connection  
  10.      */  
  11.     $readConnection = $resource->getConnection('core_read');   
  12.     
  13.     $query = 'SELECT * FROM ' . $resource->getTableName('catalog/product');   
  14.     
  15.     /**  
  16.      * Execute the query and store the results in $results  
  17.      */  
  18.     $results = $readConnection->fetchAll($query);   
  19.     
  20.     /**  
  21.      * Print out the results  
  22.      */  
  23.     echo sprintf('<pre>%s</pre>' print_r($results, true));  
<?php
 
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Retrieve the read connection
     */
    $readConnection = $resource->getConnection('core_read');
 
    $query = 'SELECT * FROM ' . $resource->getTableName('catalog/product');
 
    /**
     * Execute the query and store the results in $results
     */
    $results = $readConnection->fetchAll($query);
 
    /**
     * Print out the results
     */
    echo sprintf('<pre>%s</pre>' print_r($results, true));
  
Varien_Db_Select::fetchCol

This method is similar to fetchAll except that instead of returning all of the results, it returns the first column from each result row. In the code example below, we use Varien_Db_Select::fetchCol to retrieve all of the SKU's in our database in an array.

Php代码 复制代码   收藏代码
  1. <?php   
  2.     /**  
  3.       * Get the resource model  
  4.       */  
  5.     $resource = Mage::getSingleton('core/resource');   
  6.     
  7.     /**  
  8.      * Retrieve the read connection  
  9.      */  
  10.     $readConnection = $resource->getConnection('core_read');   
  11.     
  12.     /**  
  13.      * Retrieve our table name  
  14.      */  
  15.     $table = $resource->getTableName('catalog/product');   
  16.     
  17.     /**  
  18.      * Execute the query and store the results in $results  
  19.      */  
  20.     $sku = $readConnection->fetchCol('SELECT sku FROM ' . $table . ');   
  21.     
  22.     /**  
  23.      * Print out the results  
  24.      */  
  25.     echo sprintf('<pre>%s</pre>' print_r($results, true));  
<?php
    /**
      * Get the resource model
      */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Retrieve the read connection
     */
    $readConnection = $resource->getConnection('core_read');
 
    /**
     * Retrieve our table name
     */
    $table = $resource->getTableName('catalog/product');
 
    /**
     * Execute the query and store the results in $results
     */
    $sku = $readConnection->fetchCol('SELECT sku FROM ' . $table . ');
 
    /**
     * Print out the results
     */
    echo sprintf('<pre>%s</pre>' print_r($results, true));
 

Try this code and look at the results. Notice how all of the SKU's are in a single array, rather than each row having it's own array? If you don't understand this, try changing fetchCol for fetchAll and compare the differences.

 

Varien_Db_Select::fetchOne

Unlike the previous two methods, Varien_Db_Select::fetchOne returns one value from the first row only. This value is returned on it's own and is not wrapped in an array. In the code example below, we take a product ID of 44 and return it's SKU.

Php代码 复制代码   收藏代码
  1. <?php   
  2.     
  3.     /**  
  4.      * Get the resource model  
  5.      */  
  6.     $resource = Mage::getSingleton('core/resource');   
  7.     
  8.     /**  
  9.      * Retrieve the read connection  
  10.      */  
  11.     $readConnection = $resource->getConnection('core_read');   
  12.     
  13.     /**  
  14.      * Retrieve our table name  
  15.      */  
  16.     $table = $resource->getTableName('catalog/product');   
  17.     
  18.     /**  
  19.      * Set the product ID  
  20.      */  
  21.     $productId = 44;   
  22.     
  23.     $query = 'SELECT sku FROM ' . $table . ' WHERE entity_id = '  
  24.              . (int)$productId . ' LIMIT 1';   
  25.     
  26.     /**  
  27.      * Execute the query and store the result in $sku  
  28.      */  
  29.     $sku = $readConnection->fetchOne($query);   
  30.     
  31.     /**  
  32.      * Print the SKU to the screen  
  33.      */  
  34.     echo 'SKU: ' . $sku . '<br/>';  
<?php
 
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Retrieve the read connection
     */
    $readConnection = $resource->getConnection('core_read');
 
    /**
     * Retrieve our table name
     */
    $table = $resource->getTableName('catalog/product');
 
    /**
     * Set the product ID
     */
    $productId = 44;
 
    $query = 'SELECT sku FROM ' . $table . ' WHERE entity_id = '
             . (int)$productId . ' LIMIT 1';
 
    /**
     * Execute the query and store the result in $sku
     */
    $sku = $readConnection->fetchOne($query);
 
    /**
     * Print the SKU to the screen
     */
    echo 'SKU: ' . $sku . '<br/>';
 

When trying out this example, ensure you change the product ID to an ID that exists in your database!

 

You may think that fetchOne works the same as fetchCol or fetchAll would if you only added 1 column to the SELECT query and added a 'LIMIT 1', however you would be wrong. The main difference with this function is that the value returned is the actual value, where as Varien_Db_Select::fetchCol and Varien_Db_Select::fetchAll would wrap the value in an array. To understand this a little, try swapping the method's and comparing the results.

 

Writing To The Database

When saving a Magento model, there can be a lot of background data being saved that you weren't even aware of. For example, saving a product model can take several seconds due to the amount of related data saves and indexing that needs to take place. This is okay if you need all the data saving, but if you only want to update the SKU of a product, this can be wasteful.

 

The example code below will show you how when given a product ID, you can alter the SKU. This is a trivial example but should illustrate how to execute write queries against your Magento database.

Php代码 复制代码   收藏代码
  1. <?php   
  2.     
  3.     /**  
  4.      * Get the resource model  
  5.      */  
  6.     $resource = Mage::getSingleton('core/resource');   
  7.     
  8.     /**  
  9.      * Retrieve the write connection  
  10.      */  
  11.     $writeConnection = $resource->getConnection('core_write');   
  12.     
  13.     /**  
  14.      * Retrieve our table name  
  15.      */  
  16.     $table = $resource->getTableName('catalog/product');   
  17.     
  18.     /**  
  19.      * Set the product ID  
  20.      */  
  21.     $productId = 44;   
  22.     
  23.     /**  
  24.      * Set the new SKU  
  25.      * It is assumed that you are hard coding the new SKU in  
  26.      * If the input is not dynamic, consider using the  
  27.      * Varien_Db_Select object to insert data  
  28.      */  
  29.     $newSku = 'new-sku';   
  30.     
  31.     $query = "UPDATE {$table} SET sku = '{$sku}' WHERE entity_id = "  
  32.              . (int)$productId;   
  33.     
  34.     /**  
  35.      * Execute the query  
  36.      */  
  37.     $writeConnection->query($query);  
<?php
 
    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
 
    /**
     * Retrieve the write connection
     */
    $writeConnection = $resource->getConnection('core_write');
 
    /**
     * Retrieve our table name
     */
    $table = $resource->getTableName('catalog/product');
 
    /**
     * Set the product ID
     */
    $productId = 44;
 
    /**
     * Set the new SKU
     * It is assumed that you are hard coding the new SKU in
     * If the input is not dynamic, consider using the
     * Varien_Db_Select object to insert data
     */
    $newSku = 'new-sku';
 
    $query = "UPDATE {$table} SET sku = '{$sku}' WHERE entity_id = "
             . (int)$productId;
 
    /**
     * Execute the query
     */
    $writeConnection->query($query);
 

To test this has worked, use the knowledge gained from the first part of this tutorial to write a query to extract the SKU that has just been changed.

 

Varien_Db_Select

The Varien_Db_Select, which has been touched on in this article is a far better option for extracting/wriiting information. Not only is it easy to use, it also provides a layered of security, which if used correctly, is impenetrable. More will be covered on Varien_Db_Select (aka Zend_Db_Select) in a future article.

 

 

来源:http://fishpig.co.uk/blog/direct-sql-queries-magento.html

基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文档围绕基于遗传算法的异构分布式系统任务调度算法展开研究,重点介绍了一种结合遗传算法的新颖优化方法,并通过Matlab代码实现验证其在复杂调度问题中的有效性。文中还涵盖了多种智能优化算法在生产调度、经济调度、车间调度、无人机路径规划、微电网优化等领域的应用案例,展示了从理论建模到仿真实现的完整流程。此外,文档系统梳理了智能优化、机器学习、路径规划、电力系统管理等多个科研方向的技术体系与实际应用场景,强调“借力”工具与创新思维在科研中的重要性。; 适合人群:具备一定Matlab编程基础,从事智能优化、自动化、电力系统、控制工程等相关领域研究的研究生及科研人员,尤其适合正在开展调度优化、路径规划或算法改进类课题的研究者; 使用场景及目标:①学习遗传算法及其他智能优化算法(如粒子群、蜣螂优化、NSGA等)在任务调度中的设计与实现;②掌握Matlab/Simulink在科研仿真中的综合应用;③获取多领域(如微电网、无人机、车间调度)的算法复现与创新思路; 阅读建议:建议按目录顺序系统浏览,重点关注算法原理与代码实现的对应关系,结合提供的网盘资源下载完整代码进行调试与复现,同时注重从已有案例中提炼可迁移的科研方法与创新路径。
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文提出了一种基于非支配排序的蜣螂优化算法(NSDBO),用于求解微电网多目标优化调度问题。该方法结合非支配排序机制,提升了传统蜣螂优化算法在处理多目标问题时的收敛性和分布性,有效解决了微电网调度中经济成本、碳排放、能源利用率等多个相互冲突目标的优化难题。研究构建了包含风、光、储能等多种分布式能源的微电网模型,并通过Matlab代码实现算法仿真,验证了NSDBO在寻找帕累托最优解集方面的优越性能,相较于其他多目标优化算法表现出更强的搜索能力和稳定性。; 适合人群:具备一定电力系统或优化算法基础,从事新能源、微电网、智能优化等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统的多目标优化调度设计;②作为新型智能优化算法的研究与改进基础,用于解决复杂的多目标工程优化问题;③帮助理解非支配排序机制在进化算法中的集成方法及其在实际系统中的仿真实现。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注非支配排序、拥挤度计算和蜣螂行为模拟的结合方式,并可通过替换目标函数或系统参数进行扩展实验,以掌握算法的适应性与调参技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值