全部博文(921)
分类:
2011-01-02 20:37:47
注:具体使用可查看帮助文档。
框架中 Zend_Db的设计是极为精巧的,不仅极大的减少了编码量,提高了安全性能,而且其基于适配器(Adapter)的设计使你如果有更换数据库的需求几乎不需要怎么修改程序。好处多多呀!好吧我们花点时间研究研究它吧,在这篇文章中暂时不包括Zend_Db_Table的分析(我不是太喜欢它^_^)。 Zend Framework版本:1.9.0 让我们看一下Zend_Db的结构,上图:
一、源码目录 Adapter文件夹下是适配器:我们可以看见里面有 Db2,Mysqli,Oracle,Sqlsrv ,可见Zend Framework是支持这么多数据库,当然你也可以使用Pdo。 Profiler:可以用来debug,分析sql语句执行效率。 Statement:In addition to convenient methods such asfetchAll() andinsert(), you can use a statement object to gain more options for running queries and fetching result sets。就是可以用这个类实现更多的功能方法。 Select.php :专注于select查询的类,用来组装select查询sql语句的。 这些都是最最核心的。 二、结构分析 我们以mysqli为类,看看整个过程. 1、 首先是创建适配器 $db = Zend_Db::factory(' Mysqli ', $params); 在 Zend/Db.php文件的244行: $adapterName= strtolower($adapterNamespace.'_'.$adapter); 执行完后,$adapterName的值为 zend_db_adapter_mysqli。 在 Zend/Db.php文件的260行: $dbAdapter=new$adapterName($config); 这就创建了MySQLi的适配器了。 在Zend/Db/Adapter文件夹下,Abstract.php中 Zend_Db_Adapter_Abstract是抽象类,它声明了一些方法并实现了部分方法,Mysqli.php文件中Zend_Db_Adapter_Mysqli类继承Zend_Db_Adapter_Abstract,实现了抽象类中的部分方法,比如 _connect()方法。因为每个数据库的连接方式都有不同,所以就在这里实现了。 2、 构造查询对象,查询数据 在这里我们要做一个select查询。 示例: $db = Zend_Db::factory('Mysqli', $params); $select = $db->select(); $select->from('round_table', '*'); $select->where('noble_title = ?', 'Sir'); $select->order('first_name'); $select->limit(10,20); $result = $db->fetchAll($select); 首先是要组装出SQL语句,Zend_Db_Select 可以组装出强大的SQL语句,这个类设计的很精巧,不过这里也没法修饰,大家可以看源码。 然后执行Zend_Db_Adapter_Abstract 中的fetchAll()函数,该函数在Zend/Db/Adapter.php的701行: public function fetchAll($sql, $bind = array(), $fetchMode = null) { if ($fetchMode === null) { $fetchMode = $this->_fetchMode; } $stmt = $this->query($sql, $bind); $result = $stmt->fetchAll($fetchMode); return $result; } $stmt = $this->query($sql, $bind); 会调用自身的445行的public function query($sql,$bind=array())函数。 在这个函数中 如果$sql变量是 Zend_Db_Select 对象的话,就由 Zend_Db_Select 处理,然后返回sql语句。 当然最关键的是要看467行的 $stmt=$this->prepare($sql); 因为Zend_Db_Adapter_Mysqli类继承Zend_Db_Adapter_Abstract,所以这会调用Zend_Db_Adapter_Mysqli中的370行的prepare($sql)函数: public function prepare($sql) { $this->_connect(); if ($this->_stmt) { $this->_stmt->close(); } $stmtClass = $this->_defaultStmtClass; if (!class_exists($stmtClass)) { require_once 'Zend/Loader.php'; Zend_Loader::loadClass($stmtClass); } $stmt = new $stmtClass($this, $sql); if ($stmt === false) { return false; } $stmt->setFetchMode($this->_fetchMode); $this->_stmt = $stmt; return $stmt; } 其中:$stmtClass = $this->_defaultStmtClass; 这行代码中$stmtClass = ‘Zend_Db_Statement_Mysqli’; $stmt = new $stmtClass($this, $sql); $stmt就是一个 Zend_Db_Statement_Mysqli对象了。 回到fetchAll()函数,这里该执行 $result=$stmt->fetchAll($fetchMode); 代码了,当然这里fetchAll()函数就是Zend_Db_Statement_Mysqli中的函数了。 好了,返回结果。 这篇文章分析的很粗浅,具体的大家可以阅读源码,会有很大收获的。 |