[ZF-10089] Zend_Log
[zend.git] / documentation / manual / zh / module_specs / Zend_Db_Adapter.xml
blob608a6f8f35ea15689db288a88e4affb9e021aeca
1 <sect1 id="zend.db.adapter">
3     <title>Zend_Db_Adapter</title>
5     <sect2 id="zend.db.adapter.introduction">
7         <title>简介 </title>
9         <para>
10             <code>Zend_Db_Adapter</code>是zendfrmaeword的数据库抽象层api.
11             基于pdo, 你可以使用 <code>Zend_Db_Adapter</code> 连接和处理多种
12             数据库,包括:microsoft SQL Server,MySql,SQLite等等.
13         </para>
15         <para>要针对不同的数据库实例化一个 <code>Zend_Db_Adapter</code> 对象, 需要
16               将adapter的名字和描述数据库连接的参数数组作为参数,静态调用
17               <code>Zend_Db::factory()</code>方法。例如,连接到一个数据库名称为
18               “camelot”,用户名为“malory”的本地mysql数据库,可以进行如下操作:
19         </para>
21         <programlisting role="php"><![CDATA[<?php
23 require_once 'Zend/Db.php';
25 $params = array ('host'     => '127.0.0.1',
26                  'username' => 'malory',
27                  'password' => '******',
28                  'dbname'   => 'camelot');
30 $db = Zend_Db::factory('PDO_MYSQL', $params);
32 ?>]]></programlisting>
34         <para>
35            同样,连接到一个库名为“camelot”的SQLite数据库:
36         </para>
38         <programlisting role="php"><![CDATA[<?php
40 require_once 'Zend/Db.php';
42 $params = array ('dbname' => 'camelot');
44 $db = Zend_Db::factory('PDO_SQLITE', $params);
46 ?>]]></programlisting>
48         <para>
49           任一种方法都可以让你使用同样的api查询数据库。
50         </para>
51     </sect2>
53     <sect2 id="zend.db.adapter.quoting">
55         <title>添加引号防止数据库攻击</title>
57         <para>
58             你应该处理将在sql语句中使用的条件值;这对于防止sql语句攻击是很有好处的。
59             <code>Zend_Db_Adapter</code> (通过pdo)提供了两种方法帮助你手动的为条件值加上引号。
60         </para>
62         <para>
63             第一种是<code>quote()</code> 方法.  该方法会根据数据库adapter为标量加上
64             合适的引号;假如你试图对一个数组做quote操作, 它将为数组中
65             每个元素加上引号,并用","分隔返回. (对于参数很多的函数来说,这点是很有帮助的).
66         </para>
68         <programlisting role="php"><![CDATA[<?php
70 // 创建一个$db对象,假设数据库adapter为mysql.
72 // 为标量加引号
73 $value = $db->quote('St John"s Wort');
74 // $value 现在变成了 '"St John\"s Wort"' (注意两边的引号)
76 // 为数组加引号
77 $value = $db->quote(array('a', 'b', 'c');
78 // $value 现在变成了 '"a", "b", "c"' (","分隔的字符串)
80 ?>]]></programlisting>
82         <para>
83             第二种是 <code>quoteInto()</code> 方法. 你提供一个包含问号占
84             位符的基础字符串 , 然后在该位置加入带引号的标量或者数组. 该
85             方法对于随需构建查询sql语句和条件语句是很有帮助的. 使用
86             quoteInto处理过的标量和数组返回结果与<code>quote()</code> 方法相同.
87         </para>
89         <programlisting role="php"><![CDATA[<?php
91 // 创建一个$db对象,假设数据库adapter为mysql.
93 // 在where语句中为标量加上引号
94 $where = $db->quoteInto('id = ?', 1);
95 // $where 现在为 'id = "1"' (注意两边的引号)
97 // 在where语句中为数组加上引号
98 $where = $db->quoteInto('id IN(?)', array(1, 2, 3));
99 // $where 现在为 'id IN("1", "2", "3")' (一个逗号分隔的字符串)
101 ?>]]></programlisting>
102     </sect2>
104     <sect2 id="zend.db.adapter.查询">
106         <title>直接查询</title>
108         <para>
109             一旦你得到了一个<code>Zend_Db_Adapter</code> 实例, 你可以直接
110             执行sql语句进行查询.  <code>Zend_Db_Adapter</code> 传送这些sql语
111             句到底层的PDO对象,由PDO对象组合并执行他们,在有查询结果的情况
112             下,返回一个PDOStatement对象以便对结果进行处理。
113         </para>
115         <programlisting role="php"><![CDATA[<?php
117 // 创建一个$db对象,然后查询数据库
118 // 使用完整的sql语句直接进行查询.
119 $sql = $db->quoteInto(
120     'SELECT * FROM example WHERE date > ?',
121     '2006-01-01'
123 $result = $db->query($sql);
125 // 使用PDOStatement对象$result将所有结果数据放到一个数组中
126 $rows = $result->fetchAll();
128 ?>]]></programlisting>
130         <para>
131             你可以将数据自动的绑定到你的查询中。这意味着你在查询中可以设定
132             多个指定的占位符,然后传送一个数组数据以代替这些占位符。这些替
133             换的数据是自动进行加引号处理的,为防止数据库攻击提供了更强的安
134             全性。
135         </para>
137         <programlisting role="php"><![CDATA[<?php
139 // 创建一个$db对象,然后查询数据库.
140 // 这一次,使用绑定的占位符.
141 $result = $db->query(
142     'SELECT * FROM example WHERE date > :placeholder',
143     array('placeholder' => '2006-01-01')
146 // 使用PDOStatement对象$result将所有结果数据放到一个数组中
147 $rows = $result->fetchAll();
149 ?>]]></programlisting>
151         <para>
152             或者,你也可以手工设置sql语句和绑定数据到sql语句。这一功能通过
153             <code>prepare()</code> 方法得到一个设定好的PDOStatement对象,以便直
154             接进行数据库操作.
155         </para>
157         <programlisting role="php"><![CDATA[<?php
159 // 创建一个$db对象,然后查询数据库.
160 // 这次, 设定一个 PDOStatement 对象进行手工绑定.
161 $stmt = $db->prepare('SELECT * FROM example WHERE date > :placeholder');
162 $stmt->bindValue('placeholder', '2006-01-01');
163 $stmt->execute();
165 // 使用PDOStatement对象$result将所有结果数据放到一个数组中
166 $rows = $stmt->fetchAll();
168 ?>]]></programlisting>
169     </sect2>
171     <sect2 id="zend.db.adapter.事务处理">
173         <title>事务处理</title>
175         <para>
176             默认情况下,PDO(因此 <code> Zend_Db_Adapter</code> 也是)是采用自动commit模式。
177             也就是说,所有的数据库操作执行时就做了commit操作。假如你试图执行事务处理,最
178             简单的是调用<code> beginTransaction() </code>方法,然后选择commit或者rollback。
179             之后,<code>Zend_Db_Adapter</code>会回到自动commit模式下,直到你再次调用
180             <code>beginTransaction()</code>方法
181         </para>
183         <programlisting role="php"><![CDATA[<?php
185 // 创建一个 $db对象, 然后开始做一个事务处理.
186 $db->beginTransaction();
188 // 尝试数据库操作.
189 // 假如成功,commit该操作;
190 // 假如, roll back.
191 try {
192     $db->query(...);
193     $db->commit();
194 } catch (Exception $e) {
195     $db->rollBack();
196     echo $e->getMessage();
199 ?>]]></programlisting>
200     </sect2>
202     <sect2 id="zend.db.adapter.insert">
204         <title>插入数据行</title>
206         <para>
207             为了方便起见,你可以使用 <code> insert()</code>方法将要插入的数据绑定并创建
208             一个insert语句(绑定的数据是自动进行加引号处理以避免数据库攻击的)
209         </para>
211         <para>
212             返回值并 <emphasis>不是 </emphasis> 最后插入的数据的id,这样做的原因在于一些表
213             并没有一个自增的字段;相反的,这个插入的返回值是改变的数据行数(通常情况为1)。
214             假如你需要最后插入的数据id,可以在insert执行后调用 <code>lastInsertId() </code>方法。
215         </para>
217         <programlisting role="php"><![CDATA[<?php
220 // INSERT INTO round_table
221 //     (noble_title, first_name, favorite_color)
222 //     VALUES ("King", "Arthur", "blue");
225 // 创建一个 $db对象, 然后...
226 // 以"列名"=>"数据"的格式格式构造插入数组,插入数据行
227 $row = array (
228     'noble_title'    => 'King',
229     'first_name'     => 'Arthur',
230     'favorite_color' => 'blue',
233 // 插入数据的数据表
234 $table = 'round_table';
236 // i插入数据行并返回行数
237 $rows_affected = $db->insert($table, $row);
238 $last_insert_id = $db->lastInsertId();
240 ?>]]></programlisting>
241     </sect2>
243     <sect2 id="zend.db.adapter.update">
245         <title>更新数据行</title>
247         <para>
248             为了方便起见,你可以使用 <code>update() </code>方法确定需要update的数据并且创建一个
249             update语句(确定的数据是自动加引号处理以避免数据库攻击的)。
250         </para>
252         <para>
253             你可以提供一个可选的where语句说明update的条件(注意:where语句并
254             不是一个绑定参数,所以你需要自己数据进行加引号的操作)。
255         </para>
257         <programlisting role="php"><![CDATA[<?php
260 // UPDATE round_table
261 //     SET favorite_color = "yellow"
262 //     WHERE first_name = "Robin";
265 // 创建一个 $db对象, 然后...
266 // 以"列名"=>"数据"的格式构造更新数组,更新数据行
267 $set = array (
268     'favorite_color' => 'yellow',
271 // 更新的数据表
272 $table = 'round_table';
274 // where语句
275 $where = $db->quoteInto('first_name = ?', 'Robin');
277 // 更新表数据,返回更新的行数
278 $rows_affected = $db->update($table, $set, $where);
280 ?>]]></programlisting>
281     </sect2>
283     <sect2 id="zend.db.adapter.delete">
285         <title>删除数据行</title>
287         <para>
288             为了方便起见,你可以使用 <code>delete() </code>方法创建一个delete语句;你
289             也可以提供一个where语句以说明数据的删除条件。(注意:where语句并不是一个绑
290             定参数,所以你需要自己进行数据加引号处理)。
291         </para>
293         <programlisting role="php"><![CDATA[<?php
296 // 需要删除数据的表
297 //     WHERE first_name = "Patsy";
300 // 创建一个 $db对象, 然后...
301 // 设定需要删除数据的表
302 $table = 'round_table';
304 // where条件语句
305 $where = $db->quoteInto('first_name = ?', 'Patsy');
307 // 删除数据并得到影响的行数
308 $rows_affected = $db->delete($table, $where);
310 ?>]]></programlisting>
311     </sect2>
313     <sect2 id="zend.db.adapter.fetch">
315         <title>取回查询结果</title>
317         <para>
318             尽管你可以使用<code>query()</code>方法直接对数据库进行操作,但是通常情况
319             下,仍然还是需要选择数据行并返回结果。<code>以fetch开头</code>的一系列的
320             方法可以实现这个要求。对于每一种 <code>fetch系列 </code>的方法来说,你需
321             要传送一个select的sql语句;假如你在操作语句中使用指定的占位符,你也可以
322             传送一个绑定数据的数组对你的操作语句进行处理和替换。 <code>Fetch系列 </code>
323             的方法包括:
324          </para>
326         <itemizedlist>
327             <listitem><para><code>fetchAll()</code></para></listitem>
328             <listitem><para><code>fetchAssoc()</code></para></listitem>
329             <listitem><para><code>fetchCol()</code></para></listitem>
330             <listitem><para><code>fetchOne()</code></para></listitem>
331             <listitem><para><code>fetchPairs()</code></para></listitem>
332             <listitem><para><code>fetchRow()</code></para></listitem>
333         </itemizedlist>
335         <programlisting role="php"><![CDATA[<?php
337 // 创建一个 $db对象, 然后...
339 // 取回结果集中所有字段的值,作为连续数组返回
340 $result = $db->fetchAll(
341     "SELECT * FROM round_table WHERE noble_title = :title",
342     array('title' => 'Sir')
345 // 取回结果集中所有字段的值,作为关联数组返回
346 // 第一个字段作为码
347 $result = $db->fetchAssoc(
348     "SELECT * FROM round_table WHERE noble_title = :title",
349     array('title' => 'Sir')
352 // 取回所有结果行的第一个字段名
353 $result = $db->fetchCol(
354     "SELECT first_name FROM round_table WHERE noble_title = :title",
355     array('title' => 'Sir')
358 // 只取回第一个字段值
359 $result = $db->fetchOne(
360     "SELECT COUNT(*) FROM round_table WHERE noble_title = :title",
361     array('title' => 'Sir')
364 // 取回一个相关数组,第一个字段值为码
365 // 第二个字段为值
366 $result = $db->fetchPairs(
367     "SELECT first_name, favorite_color FROM round_table WHERE noble_title = :title",
368     array('title' => 'Sir')
371 // 只取回结果集的第一行
372 $result = $db->fetchRow(
373     "SELECT * FROM round_table WHERE first_name = :name",
374     array('name' => 'Lancelot')
377 ?>]]></programlisting>
378     </sect2>
380 </sect1>
381 <!--
382 vim:se ts=4 sw=4 et: