在这篇博客中,我们将会了解到model和collection上的一些高级操作,以此来执行复杂的sql请求。我们会了解到资源模型的model和collection。
首先,我们先看一下magento中的model和collection结构,如果你观察一下magneto的模型类,会发现它继承自Mage_Core_Model_Abstract。类Mage_Core_Model_Abstract有一些方法,如:getId(),load(),save(),delete()。
SQL和Mysql4 资源文件
我们有Magease_Test_Model_Mysql4_Test资源文件
假如我们有Magease_Test_Model_Mysql4_Test资源文件

	
		< ?php 
			class Magease_Test_Model_Mysql4_Test extends Mage_Core_Model_Mysql4_Abstract
			{
				public function _contract()
				{
					$this->_init('test/test','test_id');
				}
				public function loadByField($field,$value)
				{
					$table=$this->getMainTable();
					$where=$this->_getReadAdapter()->quoteInto("$field=?",$value);
					$select=$this->_getReadAdapter()->select()->from($table,array('tets_id'))->where($where);
					$id=$this->_getReadAdapter()->fetchOne($sql);
					return $id;
				}
			}
		? >
	


这里有一个模型文件

	
		< ? php
			class Magease_Test_Model_Test extends Mage_Core_Model_Mysql4_Abstract
			{
				public function _construct(){
					parent::_construct();
					$this->init('test/test');
				}
				public function loadByField(){
					$id=$this->getResource()->loadByField($field,$value);
					$this->load($id);
				}
			}
		? >
	


在这个文件中,有许多新的函数可供使用。让我们一个一个的试一下。
在我们的模型文件中,已经使用了这个函数

	
		$id=$this->getResource()->loadByField($field,$value);
	


$this->getResource()函数返回资模型的对象,因此我们简方便的调用了资源模型中的loadByField($field,$value)函数。
getTable()函数
现在,在Mysql4文件中的loadByField()函数中,我们已经使用了$table=$this->getMainTable()
;这个函数返回当前模型中表名,例如我们在类的函数中定义的。如果你希望得到magento中另一个sql表的名字,我们需要使用getTable().例如:$table=$this->getTable('newsletter/subscribe');

_getReadAdapter()函数
接下来是:$where=$this->_getreadAdapter()->quoteInto("$field=?",$value);
这里第一个看到的函数是$this->_getReadAdapter().这个函数返回一个对象,这个对象具有执行数据库查询的功能,例如;fetch(),fetchAll(),query()等
接下来,在读取结合口中,我们可以执行以下操作:
1,fetchAll():以多维数组的方式返回全部的数据表,就像select查询一样。例如:如果我们向执行一个sql语句"select * from table_name",我们将使用fetch()函数来获得所有的值。
2,fetchRow():返回数据表的一行,就像select查询一样。例如:如果你想执行sql操作"select * fromtable where id='1'",你可以使用fetchRow()来获取一行。
3,fetchCol():返回数据表的一列,就像select查询一样。例如:如果查询是从表中选择一个名字,我们可以使用fetchCol()函数。
4,fetchOne():返回一个值。例如某一行某一列。例如:如果sql语句是:select count(*) fromtable,然后你就可以使用fetchOne()了。
读取接口同样还有许多别的函数,但是上面那些是我们使用的比较重要的函数。

_quoteInfo()函数
另一个我们使用的函数就是_quoteInto():这个函数被用来新建我们的where条件。在这里,实际的值被替换成我们写的问号。例如:$this->_getReadAdapter()->quoteInto('user_id=?',3)翻译成"user_id=3"。quoteInto()另一个经常使用的变化是:

	
		$where=$this->_getReadAdapter()->quoteInto("$field IN(?)",array(1,2,3));
	


这个可以翻译成"field in(1,2,3)"。

深入了解quoteInto()函数:如果我们有可供使用的多重where条件,


               $where=$this->_getReadAdapter()->quoteInto("$field=? AND",$value).$this->_getReadAdapter()->quoteInto("field1=? OR",$value1 ).$this->_getReadAdapter()->quoteInto("$field2=?",$value2)


用这种方法,我们可以获得多重的where条件:"$field=$value AND $field1=$value1 OR $field2=$value"。
继续我们资源模型中的loadByField函数,下一个$select=$this->_getReadAdapter()->select()->from($table,array('tets_id'))->where($where);在这里,我们已经使用select()创建了select查询,基于这些使用我们叫它from()函数。

from()函数

from()函数有许多不同的参数,如果你仅仅想使用一个简单地select * 查询,你只需要传递表名,例如:from($table).

但是现在,我想要选择test_id这一列,所以我传递包含着列的名字的数组来进行选择。例如:array('test_id')
。如果我们想要选择多重列,我们需要array('test_id','col1','col2')。这些会建立一个sql语句,比如:"select test_id,col1,col2 from $table"。但是假如我们想要这么一个sql语句:"select test_idad id,col1 as column1 from $table",我会调用:

	
		from($table,array('id'=>'test_id','column1'=>'col1'));
	


注意:如果你下你给看到有你的函数产生的确切的sql,你可以在任何时候这么做:

	
		< ?php echo $select? >
	


再次回到loadByField()函数,最后一行:

	
		$id=$this->_getReadAdapter()->fetchOne($sql);
	


这些上面已经解释过了,这里就不再重复。

select对象
上面我们所使用的select()函数返回的是一个select对象,它提供给我们许多用于在sql查询上执行所有操作的函数。select对象的类是Varien_Db_Select,那里你可以看到所有函数的更多详细情况。让我们看一下下方的php代码。

	
		public function getAll(){
			$table=$this->getMainTable();
			$where=$this->_getReadAdapter()->quoteInto("id=?",123);
			$select=$this->_getReadAdapt()->select()->from($table)->columns(array('test_id'))->where($where)->limit(10,5)->order('created_time')->group('list_id')->having('list_id>?',10);
			echo $select;
		}
	


可以看到,在select对象中的所有的函数返回select对象本身。由于这一点,我们可以链接函数。
在这个例子中,我们已经使用了了几乎所有的你需要添加的sql select变量,这些变量稍后将会被覆盖。
让我们将这些函数一个一个的看一遍:
1.select():用来初始化sql查询。它返回的是我们进行所有操作的Select对象。
2.from():用来进行select查询的表名,在上面的细节中我们已经了解这个函数了。
3.columns():在这里我们可以指定精确的列用来查询。
4.where():用来给出where条件。
5.limit():需要参数。第一个参数是返回的行数,第二个参数是开始位置。所以在当前这个例子中,它意味着返回10行,留下前5行。在sql查询中使用语法LIMIT 10 OFFSET 5,而不是LIMIT10,5。
6.order():你可以设置你需要的结果排序方式。默认的排序方式是升序。但是如果你需要降序,你可以这样(array('created_time_Zend_Db_Select::SQL_DESC'))
7.group():在select查询中按字段对结果进行分组。
Having():通过条件按字段对结果进行分组。

JOINS
让我们看一个简单的函数:

	
		public function joinUs(){
			$table=$this->getMainTable();
			$table2=$this->getTable('customer/entity');
			$cond=$this->_getReadAdapter()->quoteInto('t1.id=t2.customer_id','');
			$where=$this->_getReadAdapter()->quoteInto("t1.list_id='?'",123);
			$select=$this_getReadAdapter()->select()->from(array('t1'=>$table))->join(array('t2'=>$table2),$cond)->where($where);
			echo $select."< br/ >";
			$select=$this_getReadAdapter()->select()->from(array('t1'=>$table))->joinLeft(array('t2'=>$table2),$cond)->where($where);
			echo $select."< br/ >";
			$select=$this_getReadAdapter()->select()->from(array('t1'=>$table))->joinRight(array('t2'=>$table2),$cond)->where($where);
			echo $select."< br/ >";
			echo $select."< br/ >";
	}
	


这时在我的电脑上的输出:

	
		SELECT 't1'.*,'t2'.* FROM 'aws' AS 't1' INNER JOIN 'customer_entity' AS 't2' ON t1.id=t2.customer_id WHERE (t1.list_id="123")
		SELECT 't1'.*,'t2'.* FROM 'aws' AS 't1' LEFT JOIN 'customer_entity' AS 't2' ON t1.id=t2.customer_id WHERE (t1.list_id="123")
		SELECT 't1'.*,'t2'.* FROM 'aws' AS 't1' RIGHT JOIN 'customer_entity' AS 't2' ON t1.id=t2.customer_id WHERE (t1.list_id="123")
	


在这里你可以清楚地看到joins是如何使用的。这里不需要过多的解释,函数的调用是不言而喻的。如果需要,我们同样也可以在任何查询中使用joinCross,joinFull,joinNatural。具体细节请看Varien_Db_Select类

COUNT,MAX
让我们看另一段简单代码:

	
		public function countUs(){
			$table=$this->getMainTable();
			$where=$this->_getReadAdapter()->quoteInto("id=?",123);
			$select=$this->_getReadAdapter()->select()->from($table)->reset('columns')->columns(new Zend_Db_Expr('count(*)'));
			echo $select.'< br >';
			$select=$this->_getReadAdapter()->select()->from($table)->reset('columns')->columns(new Zend_Db_Expr('max(list_id)'));
			echo $select.'< br >';
		}
	


输出:

	
		SELECT count(*) FROM 'aws'
		SELECT max("list_id") FROM 'aws'
	


可以看到,使用类Expr,你可以使用sql平均函数
query()函数
最后如果你有一个复杂的sql查询,你可以使用查询函数来进行简单的操作。
$sql='...complex...';
$this->_getReadAdapter()->query($sql);

UPDATE,DELETE 查询

	
		public function updateUs(){
			$table=$this->getMainTable();
			$where=$this->_getWriteAdapter()->quoteInto('id=?',1);
			$query=$this->_getWriteAdapter()->update($table,array('product_id'=>2,'file_id'=>3),$where);
		}
	


这里你可以看到如何进行update查询的

	
		UPDATE 'aws' SET 'product_id'=?,'file_id'=? WHERE (id=1)
	


对于delete查询,它很简单:

 	
 		$this->_getReadAdapter()->delete($table,$where)->limit(1);
 	
 


重要提示:只在资源文件中执行sql查询对magento来说是一个不错的习惯。你可以在模型、phtml或者别的任何一个文件中读取接口对象并且在任何文件中做上述操作,但是只在资源/mysql4进行查询是一个很好的习惯。