17.4.4 ADODB的查询方法
ADODB的查询方法如下。
1.直接查询
Excute()方法通过连接句柄执行SQL查询,并返回一个变量,如下:
$sql='SELECT * FROM ice_cream WHERE flavor LIKE ?'; $res = $cnx->Execute($sql,array('Chocolate'));
2.缓存查询
ADODB提供内置的缓存机制,CacheExecute()方法用于每次查询数据时,会把相应的结果序列化后保存到文件中,以后同样的查询语句就可以不用直接查询数据库,而是从缓存文件中获取,从而提高Web系统的性能。CacheExecute()方法的格式如下:
CacheExecute($ttc,$sql)
该方法以缓存的形式执行一段查询,其中$ttc为缓存的时间,请看如下代码:
$ADODB_CACHE_DIR = "/var/tmp/adodb_cache"; //缓存保存的文件目录 $sql = "SELECT surname, age FROM employees"; //构造一个查询 $rs = &$db->CacheExecute(600,$sql); // 缓存式查询,缓存将被保存600秒后更新
3.清除缓存
CacheFlush()
该方法用来清除所有ADODB数据库的缓存。
17.4.5 移动记录集
记录集(Record Set):从执行的方法中返回指定的记录,使用moveFirst()、moveLast()、moveNext()和move($n)方法访问记录集中的一个指定记录。例如:
$rs=$cnx->Execute('SELECT flavor,price FROM ice_cream'); $rs->MoveLast(); print "Flavor ".$rs->fields[0]." costs " .$rs->fields[2]."\n"; $rs->MoveFirst(); //省略... $rs->Move(2); //省略... $rs->MoveNext();
设置一个全局变量$ADODB_FETCH_MODE,从ADODB_FETCH_NUM(或从ADODB_FETCH_ASSOC返回)中取得数字索引(或关联索引)数组。例如:
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC ; $rs=$cnx->Execute('SELECT flavor,price FROM ice_cream'); print "<table>\n"; while (! $rs->EOF) { print "<tr><td>".$rs->fields['flavor']}."</td>". "<td>".$rs->fields['price']"."</td></tr>\n"; $rs->MoveNext(); } print "</table>\n";
FetchObject()方法也是一个记录集变量。
17.4.6 使用ADODB生成HTML
ADODB的rs2html($res)函数,它提供一个简单的方法,从$res变量中的记录自动生成HTML表格。它在tohtml.inc.php中,使用时需要包含进来,如下代码:
require 'adodb/tohtml.inc.php'; //引入rs2html函数 require 'adodb/adodb.inc.php'; //省略... $rs = $cnx->Execute('SELECT flavor,calories,price FROM ice_cream'); rs2html($rs);
使用rs2html($res,'CLASS="myClass")这种格式,表示指定表格使用的myClass的样式表类进行显示。
17.4.7 使用ADODB进行分页
ADODB_Pager(该方法定义在adodb-pager.inc.php中)提供一种简单分页显示记录的方法。
require 'adodb/adodb.inc.php'; require 'adodb/adodb-pager.inc.php'; $pager=new ADODB_Pager($cnx,"SELECT id,flavor,price FROM ice_cream_big"); $pager->Render();
使用$pager->Render($num)来设置每次显示的行数,默认值为10。
17.4.8 生成下拉选择菜单
getMenu($selectName)方法将帮助我们生成一个<select>标签,即从记录集中生成一个下拉菜单。其中,$selectName是该表单中select的name标签。例如:
$rs = $cnx->execute('SELECT flavor,id FROM ice_cream'); print $rs->GetMenu('which_flavor');
相关说明如下:
getMenu($sN,$selected,$blank,$mult,$nm):其中,$selected (string)为默认选择的值/项。
$blank (boolean):默认初始值或布尔值为true时,下拉选项为空。
$mult (boolean):下拉菜单是否可以允许多选。
$nm (integer):设置菜单多重选择的属性,也就是默认几行。
17.4.9 ADODB开发实例
为了能更好地理解和使用ADODB,下面一起做一个完整的实例。
首先准备一个简单的表,名为“library”,用于保存书籍目录。结构与记录内容如下:
mysql> SELECT * FROM library;
+----+--------------------+---------------+
| id | title | author |
+----+--------------------+---------------+
| 14 | ASP.NET 2.0网络编程 | Dennis Lehane |
| 15 | For Kicks | Dick Francis |
| 16 | XML and PHP | Vikram Vaswani |
| 17 | Where Eagles Dare | Jack Higgins |
+----+--------------------+----------------+
在library表中,包含3个字段,分别为:
id——主键,用于保存书的序列号;
title——用于保存书的标题;
author——用于保存作者信息。
下面看使用PHP的传统开发方式,即使用PHP的MySQL API库进行编写的代码,如下:
<?php // 创建一个数据库连接 $connection = mysql_connect("localhost", "root", "passwd") or die ("Unable to connect!"); // 选择数据库 mysql_select_db("adodb") or die ("Unable to select database!"); // 构建SQL和开始查询 $query = "SELECT * FROM library"; $result = mysql_query($query) or die ("Error in query: $query. " . mysql_error()); // 遍历记录集,并显示字段的内容 while ($row = mysql_fetch_row($result)){ echo "$row[1] - $row[2]\n"; } // 显示返回的记录行数 echo "\n[" . mysql_num_rows($result) . " 行记录被返回]\n"; // 关闭数据库连接 mysql_close($connection); ?>
输出结果如下:
ASP.NET 2.0网络编程- Dennis Lehane
For Kicks - Dick Francis
XML and PHP - Vikram Vaswani
Where Eagles Dare - Jack Higgins
[4 行记录被返回]
可以看到此例子比较简洁,连接到数据库,执行查询,取回结果后显示出来。
上述 例子用mysql_fetch_row()的抽取功能,取得记录后生成一个连续整数的索引数组,数据内容分别对应数据表中的字段。与此相似的还有 mysql_fetch_assoc(),它生成一个关联数组,或者mysql_fetch_object函数,它生成一个对象(其属性相当于字段名)。
这段代码是没有任何问题的,但如果我们想从MySQL迁移到PostgreSQL数据库或者Oracle怎么办呢?代码需要重写了!这时,就需要数据抽象层ADODB上场了。
我们把上例改用ADODB重新编写,请看下面的代码:
<?php include_once("libs/adodb/adodb.inc.php"); // 创建一个MySQL连接对象 $db = NewADOConnection("mysql"); // 打开一个数据库连接 $db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!"); // 执行一个查询 $query = "SELECT * FROM library"; $result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg()); // 遍历返回的记录集内容,打印返回列的内容:TITLE 和AUTHOR while (!$result->EOF) { echo $result->fields[1] . " - " . $result->fields[2] . "\n"; $result->MoveNext(); } // 显示返回的记录行数 echo "\n[" . $result->RecordCount() . " 行记录被返回]\n"; // 关闭数据库连接 $db->Close(); ?>
这个程序和上面程序的实现功能是一样的,但是由于采用ADODB抽象层,而没有采用PHP的本地API(mysql或mysqli扩展),因此可以灵活地更换数据库系统,无论哪个数据库以及如何更换,这段代码都是可用的。
下面对上述代码进行详细的解释说明。首先,我们引用ADODB主类文件:
<?php include_once("libs/adodb/adodb.inc.php");
实际上,ADODB库并非只有这一个文件,事实上有超过30个不同的文件,负责驱动不同的数据库系统。我们不用担心是否完全将类包含完全,该文件会自动识别和匹配当前的PHP版本及数据库系统,并自动包含相关的类库文件。
然后,创建ADODB的对象实例:
// 创建一个mysql连接对象 $DB = NewADOConnection("mysql");
通过对象的构造参数,告诉ADODB连接数据库,这里连接的是MySQL数据库服务器,对于其他数据库,还可以相应地使用"pgsql"或"oci8"。可以连接的数据库及连接标识参见表17-1。
接下来,连接数据库,这是通过Connect()方法完成的,必须设置一套连接参数:
// 打开一个数据库连接 $db->Connect("localhost", "root", "passwd", "adodb") or die("Unable to connect!");
以上代码试图打开一个MySQL连接,3个参数分别为主机名、用户名和密码。
一旦Connect()方法建立连接后,就可以调用该对象的Execute()方法进行SQL数据库查询。
// 构造并执行一个查询 $query = "SELECT * FROM library"; $result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg());
当查询执行成功后,则返回含有查询结果的对象。特别说明的是errormsg()方法,可以用来获取查询的一个错误信息。
从返回的结果集中循环取值:
// 遍历返回的记录集内容,打印返回列的内容:TITLE 和AUTHOR while (!$result->EOF) { echo $result->fields[1] . " - " . $result->fields[2] . "\n"; $result->MoveNext(); }
在这种情况下,在循环体内,使用对象的movenext()方法进行记录的移动,每次循环打印后就移动到下一条记录。
取得记录集后,可以使用recordcount()方法取得记录的条数。
// 遍历返回的记录集内容,打印返回列的内容:TITLE 和AUTHOR echo "\n[" . $result->RecordCount() . " 行记录被返回]\n";
最后,使用Close()方法关闭数据库的连接。
// 关闭数据库连接 $db->Close();
如果有人决定要更换数据库,唯一需要改变的是将上述脚本的连接改为新的数据库名称和主机地址即可。
这就是数据抽象层最好的优势之一,它提供一些尽可能通用的方法,将与数据库打交道的代码隐藏在内部,从而使PHP代码简单、清爽、可维护性好,并且缩短开发周期,以及拥有软件包的整体感。
ADODB还提供了一些不同的方法处理结果记录集。 例如,我们可以取回结果集为一个关联数组。请看如下脚本:
<?php include_once("libs/adodb/adodb.inc.php"); // 创建一个mysql连接实例对象 $db = NewADOConnection("mysql"); // 打开一个数据库连接 $db->Connect("localhost", "john", "doe", "adodb") or die("Unable to connect!"); // 将结果保存为一个关联数组,也可以使用数值3 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; // 构造并执行一个查询 $query = "SELECT * FROM library"; $result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg()); // 遍历记录集,显示列的内容:TITLE 和AUTHOR while (!$result->EOF) { echo $result->fields['title'] . " - " . $result->fields['author'] . "\n"; $result->MoveNext(); } // 取得和显示返回的记录行数 echo "\n[" . $result->RecordCount() . " 行记录被返回]\n"; // 关闭数据库连接 $db->Close(); ?>
在这个例子里,$ADODB_FETCH_MODE的值用于确定ADODB如何构建结果记录集。你也可以把取得的行转变为一个对象,其属性相当于字段名,这就是ADODB的FetchNextObject()方法,请看如下脚本例子:
<?php include("libs/adodb/adodb.inc.php"); // 创建一个mysql连接对象实例 $db = NewADOConnection("mysql"); // 打开一个数据库连接 $db->Connect("localhost", "john", "doe", "adodb") or die("Unable to connect!"); // 构造并执行一个查询 $query = "SELECT * FROM library"; $result = $db->Execute($query) or die("Error in query: $query. " . $db->ErrorMsg()); // 遍历记录集,显示列的内容:TITLE 和AUTHOR while ($row = $result->FetchNextObject()) { echo $row->TITLE . " - " . $row->AUTHOR . "\n"; } // 取得和显示返回的记录行数 echo "\n[" . $result->RecordCount() . " 行记录被返回]\n"; // 关闭数据库连接 $db->Close(); ?>
值得一提的是,FetchNextObject()方法可以自动在记录集中移动到下一行,我们不需要再使用MoveNext()方法,当到达记录集尾部时,该方法返回false。