⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdbc-spec.frame7.html

📁 JDBC入门中文文档
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>

<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=gb2312">
<title></title>
</head>

<body bgcolor="#ffffff">

<table width="600">
  <tr>
    <td><font size="-1"><a href="jdbc-spec.frame.html">目录</a> | <a
    href="jdbc-spec.frame6.html">上一页</a> | <a href="jdbc-spec.frame8.html">下一页</a> 
    </font></td>
    <td align="right"><i>JDBC<sup><font size="-2">TM</font></sup> 指南:入门</i></td>
  </tr>
</table>

<hr>

<p><br>
<a name="20376"></a> </p>

<h2>7 传送参数和接收结果</h2>

<p>有关完整的接口描述,参见单独的 JDBC API 文档。 </p>

<p><a name="5514"></a><strong>另请参阅附录 <a href="jdbc-spec.frame15.html#3883">A</a> 
中所述的被拒绝的“Holder”机制。</strong></p>

<p><a name="4149"></a> </p>

<h3>7.1 查询结果</h3>

<p>执行查询语句的结果将生成一些行,这些行可由 java.sql.ResultSet 
对象访问。ResultSet 对象提供一套“get”方法,允许访问当前行的不同列。利用 
ResultSet.next 方法可实现 ResultSet 行之间移动。 </p>

<pre><code>// 我们将执行返回行集合的 SQL 语句,
</code></pre>

<pre><code>// 其中列 1 为 int、列 2 为 String
</code>// 列 3 为字节数组</pre>

<pre><code>// 
</code></pre>

<pre><code>java.sql.Statement stmt = conn.createStatement();
</code></pre>

<pre><code>ResultSet r = stmt.executeQuery(&quot;SELECT a, b, c FROM Table1&quot;);
</code></pre>

<pre><code>while (r.next()) {
</code></pre>

<pre><code>	// 打印当前行的值
</code></pre>

<pre><code>	int i = r.getInt(&quot;a&quot;);
</code></pre>

<pre><code>	String s = r.getString(&quot;b&quot;);
</code></pre>

<pre><code>	byte b[] = r.getBytes(&quot;c&quot;);
</code></pre>

<pre><code>	System.out.println(&quot;ROW = &quot; + i + &quot; &quot; + s + &quot; &quot; + b[0]);
</code></pre>

<pre><code>}
</code></pre>

<p>指定列的方法有两种:列索引(更有效)或列名(更方便)。对应地,我们提供以列索引为参数的 
getString 方法和以列名为参数的 getString 方法。 </p>

<p><a name="26252"></a><strong>评论家使我们确信:我们必须同时支持列索引和列名。某些评论家强调指出,他们需要高效的数据库访问,因此喜欢用列索引,而其它评论家强调他们需要方便地使用列名(注意,某些 
SQL 
查询可返回不含列名或含多个相同列名的表。这种情况下,程序员应使用列号)。 
</strong></p>

<p>为了最大程度的可移植性,应按由左至右的顺序读取某行的各列,且每列只能读一次。这反映了在某些基本数据库协议中存在实现限制。 
</p>

<p><a name="26308"></a> </p>

<h4>7.1.1 查询结果的数据转换</h4>

<p>ResultSet.getXXX 方法试图将数据库返回的 SQL 类型转换为 getXXX 
方法返回的 Java 类型。 </p>

<p><a name="28700"></a><a href="jdbc-spec.frame7.html#30717">第 21 页的表 1</a> 
列出了通过 getXXX 方法实现从 SQL 类型到 Java 
类型的转换。例如,可以使用 getInt 尝试将 SQL VARCHAR 
值作为整数读取,但不能将 SQL FLOAT 作为 java.sql.Date 读取。 </p>

<p>如果试图进行非法转换或数据转换失败(例如对 SQL VARCHAR 值“foo”执行 
getInt),则将抛出 SQLException。 </p>

<p><a name="30761"></a> </p>

<p align="center"><a name="30758"></a> <a name="30717"></a><img src="table1.gif"
width="522" height="567"> </p>

<p><a name="30760"></a> </p>

<h4>7.1.2 空结果值</h4>

<p>要确定给定结果值是否为 SQL“NULL”,则必须首先读取列,然后使用 
ResultSet wasNull 方法查看是否返回了 SQL“NULL”(另请参阅附录 <a
href="jdbc-spec.frame15.html#25317">A.9</a>)。 </p>

<p><a name="25307"></a>当使用 getXXX 方法读取 SQL“NULL”时,将得到: 

<ul>
  <p><a name="26541"></a></p>
  <li>返回 Java 对象的 getXXX 方法返回的 Java“null”值<br>
    <br>
    <a name="26542"></a> </li>
  <li>getByte、getShort、getInt、getLong、getFloat 和 getDouble 返回的零值<br>
    <br>
    <a name="27824"></a> </li>
  <li>getBoolean. 返回的 false 值<br>
    <br>
  </li>
</ul>

<p><a name="27826"></a></p>

<h4>7.1.3 检索特大行值</h4>

<p>JDBC 允许使用 getBytes 和 getString 检索任意大的 LONGVARBINARY 或 
LONGVARCHAR 数据,范围只要不超出 Statement.getMaxFieldSize 
值限定的界限。但是,应用程序设计人员会经常发现,在相对较小的固定块中检索非常大的数据将更为方便。 
</p>

<p>为适应这一点,ResultSet 类可返回 java.io.Input 
流,以块为单位读取数据。但是,因为调用 ResultSet 的下一个“get”将会使这些流自动关闭,因此必须立即访问其中的每个流。<strong>这反映了对大块访问的基本实现限制。</strong></p>

<p><a name="25069"></a>Java 流返回无类型的字节,并且对 ASCII 和 Unicode 
都适用。我们定义了三种独立的获得流的方法。 GetBinaryStream 
返回的流只提供来自数据库的原字节而不进行任何转换。GetAsciiStream 
返回的流提供单字节 ASCII 字符。GetUnicodeStream 
返回的流则提供两个字节的 Unicode 字符。 </p>

<p><a name="25098"></a>例如: </p>

<pre><code>java.sql.Statement stmt = conn.createStatement();
</code></pre>

<pre><code>ResultSet r = stmt.executeQuery(&quot;SELECT x FROM Table2&quot;);
</code></pre>

<pre><code>// 在 4 K 的块中检索列 1 的结果:
</code></pre>

<pre><code>byte[] buff = new byte[4096];
</code></pre>

<pre><code>while (r.next()) {
</code></pre>

<pre><code>	java.io.InputStream fin = r.getAsciiStream(&quot;x&quot;);
</code></pre>

<pre><code>	for (;;) {
</code></pre>

<pre><code>		int size = fin.read(buff);
</code></pre>

<pre><code>		if (size == -1) {
</code></pre>

<pre><code>			break;
</code></pre>

<pre><code>		}
</code></pre>

<pre><code>		// 将新填充的缓冲区传给某些 ASCII 输出流:
</code></pre>

<pre><code>		output.write(buff, 0, size);
</code></pre>

<pre><code>	}
</code></pre>

<pre><code>}
</code></pre>

<h4>7.1.4 可选或多重 ResultSet</h4>

<p>我们通常希望使用 executeQuery(返回单个 ResultSet)或 executeUpdate(可用于任何数据库修改语句,且返回更新行的计数)执行 
SQL 语句。 </p>

<p><a name="20214"></a>但在某些环境下,应用程序在语句执行前可能不知道给定语句是否返回 
ResultSet。另外,某些存储过程可能返回多个不同的 ResultSet 和/或更新计数。 
</p>

<p><a name="20231"></a>为适应这些需要,我们提供一种机制,以使应用程序能执行语句,然后处理 
ResultSet 的任意集合并更新计数。该机制基于完全通用的“execute”方法,并得到方法 
getResultSet、getUpdateCount 和 getMoreResults 
的支持。这些方法允许应用程序每次查询一个语句结果并确定给定结果是 
ResultSet 还是更新计数。 </p>

<p><a name="20240"></a> </p>

<h3>7.2 传递 IN 参数</h3>

<p>为将参数传递到 SQL 语句,java.sql.PreparedStatemen 类提供了一系列 
setXXX 
方法。这些方法可用来在每一次语句执行前填充参数域。一旦为给定语句定义了参数值,该参数值就可用于语句的多重执行,直到调用 
PreparedStatement.clearParameters 清除这一参数为止。 </p>

<pre><code>java.sql.PreparedStatement stmt = conn.prepareStatement(
</code></pre>

<pre><code>					&quot;UPDATE table3 SET m = ? WHERE x = ?&quot;);
</code></pre>

<pre><code>// 传递两个参数。一个在每次 for 循环中都改变,
</code></pre>

<pre><code>// 另一个为常量。
</code></pre>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -