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

📄 jdbc2.0.frame7.html

📁 JDBC的学习文档
💻 HTML
字号:
<!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="100%">
  <tr>
    <td><font size="-1"><a href="jdbc2.0.frame.html">目录</a> | <a
    href="jdbc2.0.frame6.html">上一页</a> | <a href="jdbc2.0.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="285951"></a> </p>

<h2>7 对 Java 对象的持久性</h2>

<p>JDBC 1.0 API 提供了一些对存储 Java 对象和经由 <code>getObject()</code> 和 
<code>setObject()</code> 机制从数据库检索 Java 对象的支持。JDBC 2.0 API 
通过提供新型的元数据功能(可以使用元数据功能来检索对数据源所含 
Java 对象的描述)从总体上增强了 JDBC 驱动程序实现 Java 
对象持久性的能力。Java 类的实例可以作为可序列化的 Java 
对象(或其它某种特定于厂商的格式)存储在数据库中。如果采用了对象序列化,则可以根据 
Java 对象序列化所指定的规则处理对象之间的引用。</p>

<p><a name="297434"></a>本章所述的 JDBC 2.0 API 功能可支持新一代的能感知 
Java 的数据库管理系统,称为 <em>Java 关系式 DBMS</em>。Java 关系式 DBMS 
用 Java 
对象类型扩展了数据库的类型系统,同时允许用户编写引用这些类型的查询。现在有几家数据库厂商正在创建具有 
Java 
关系式能力的产品。本章所述的各种机制是可选的。不支持本章所述功能的 
JDBC 驱动程序不需要实现这些功能。</p>

<p><a name="293109"></a>让我们先看看典型的 Java 应用程序如何利用 JDBC API 
来存储和检索 Java 对象。</p>

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

<h3>7.1 检索 Java 对象</h3>

<p>下例显示了利用 JDBC 如何检索对象。示例查询引用了 <code>PERSONNEL</code> 
表,而表中包含了称为 <code>Employee</code> 的列,列中包含 Java 类 <code>Employee</code> 
的实例。此处,列名 <code>Employee</code> 和 Java 
类名相同,但是这并非是 JDBC 所要求的。事实上,由于目前引用 Java 
类型的 SQL 查询没有公认的标准语法,所以 JDBC 
并没有要求必须使用任何特定的查询语法。</p>

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

<blockquote>
  <pre>ResultSet rs = stmt.executeQuery(
	&quot;SELECT Employee FROM PERSONNEL&quot;);
rs.next();
Employee emp = (Employee)rs.getObject(1);

</pre>
</blockquote>

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

<p><a name="292884"></a>本例从 <code>PERSONNEL</code> 表中选择了所有的 <code>Employee</code> 
实例。调用 <code>ResultSet.next() </code>方法将结果集定位到包含 <code>Employee</code> 
的第一行。然后,示例应用程序通过调用 <code>ResultSet.getObject()</code> 
获得 <code>Employee</code> 实例。这将导致 JDBC 
驱动程序(或许是通过恢复序列化的对象实例)构造 <code>Employee</code> 
类的实例,然后将实例作为 <code>java.lang.Object</code> 
返回,而应用程序将其限定为 <code>Employee</code>。</p>

<p><a name="293026"></a>请注意:上例中没有包含对 JDBC 1.0 API 
的增加部分,而只是可能需要一些 JDBC 未规定的扩展的 SQL 
查询语法格式。另外,我们注意到以上所示的 JDBC 
代码还可用来检索映射成 Java 类的 SQL 
自定义类型的数据。稍后一章中我们将详细讨论这一点。</p>

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

<h3>7.2 存储 Java 对象</h3>

<p>下例说明了利用 JDBC 更新 Java 
对象及使得对象的更新副本能持久的过程。</p>

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

<blockquote>
  <pre>emp.setSalary(emp.getSalary() * 1.5);
PreparedStatement pstmt = con.preparedStatement(
&quot;UPDATE PERSONNEL SET Employee = ? WHERE Employee.no = 1001&quot;);
pstmt.setObject(1, emp);
pstmt.executeUpdate();


</pre>
</blockquote>

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

<p>下例给某雇员的工资上涨了 50% 。它首先调用 <code>Employee.setSalary()</code> 
方法来更新该雇员的工资额。请注意:JDBC 并没有规定 <code>Employee</code> 
类上的方法的语义。此处,我们假定 <code>Employee</code> 类是一般的 
Java 类,因此调用 <code>Employee.setSalary() </code>只是改变 <code>Employee</code> 
实例中某些私有数据域的值。例如,调用 <code>Employee.setSalary()</code> 
并不会更新数据库,尽管另外一种替代实现可以做到这一点,实际上也就使数据库更新对于使用 
<code>Employee</code> 类的应用程序成为“透明的”。</p>

<p><a name="293065"></a>接着,它将利用扩展的 SQL UPDATE 
命令(本例中所用的查询语法也不是 JDBC 必需的)来创建 <code>PreparedStatement</code> 
对象。UPDATE 命令表示要改变 <code>PERSONNEL</code> 表中指定行的 <code>Employee</code> 
列。<code>PreparedStatement.setObject()</code> 的作用是将 <code>Employee</code> 
对象传递给预先准备好的语句,而 <code>executeUpdate()</code> 
方法更新存储在数据库中的 <code>Employee</code> 值。</p>

<p><a name="288788"></a>请再次注意:上例并没有涉及 JDBC 1.0 API 
没有的语法增加部分。另外,如果要将 Employee 类映射到 SQL 
自定义类型,仍可以使用与此相同的 JDBC 代码。</p>

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

<h3>7.3 附加元数据 </h3>

<p>JDBC 2.0 API 
包含了一种新型的元数据支持,可以使应用程序获得对存储在数据源中的 
Java 对象的完整描述。</p>

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

<h4>7.3.1 标识 Java 对象</h4>

<p>在 <code>java.sql.Types </code>中新增了一种类型代码 <code>JAVA_OBJECT</code>,可用来表示 
Java 对象类型。<code>JAVA_OBJECT</code> 类型代码是由诸如 <code>DatabaseMetaData.getTypeInfo() 
</code>和 <code>DatabaseMetaData.getColumns()</code> 的方法返回的。例如,如果 
DBMS 支持是 Java 类的类型,则 <code>DatabaseMetaData.getTypeInfo()</code> 
将返回包含有以下项的结果集: </p>

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

<ul>
  <li><a name="297536"></a><strong>TYPE_NAME</strong> String =&gt; 
    特定于数据源的名称(可以为空) <a name="297537"></a></li>
  <li><strong>DATA_TYPE</strong> short =&gt; java.sql.Types.JAVA_OBJECT</li>
  <li>等等<a name="297539"></a> </li>
</ul>

<p>TYPE_NAME 列包含了 Java 对象的数据源特定的术语,例如“JavaObject”、“Serialized(序列化的)”等等。TYPE_NAME 
可以为空。</p>

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

<h4>7.3.2 特定于检索架构的 Java 类型描述</h4>

<p>在用 Java 类来定义架构的表之前,通常用特定的数据库架构来注册 
Java 类。可以通过调用 <code>DatabaseMetaData.getUDTs()</code> 
方法来检索有关特定于架构的自定义类型(<code>JAVA_OBJECT</code> 
类型是其中的一种)的信息。例如, </p>

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

<blockquote>
  <pre><code>int[] types = {Types.JAVA_OBJECT};
ResultSet rs = dmd.getUDTs(&quot;catalog-name&quot;, &quot;schema-name&quot;,
	&quot;%&quot;, types);
</code></pre>
</blockquote>

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

<p><a name="297558"></a>将返回在 <code>catalog-name.schema- name </code>架构中<strong>定义的</strong>所有 
Java 对象的描述。如果驱动程序不支持 UDT 或没有找到匹配的 UDT,则返回空结果集。</p>

<p><a name="297711"></a>每种类型描述都有以下几列: </p>

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

<table Border="0">
  <tr>
    <td><strong>TYPE_CAT </strong></td>
    <td>String =&gt; 类型的目录(可以为空) </td>
  </tr>
  <tr>
    <td><strong>TYPE_SCHEM </strong></td>
    <td>String =&gt; 类型的架构(可以为空) </td>
  </tr>
  <tr>
    <td><strong>TYPE_NAME </strong></td>
    <td>String =&gt; 数据库类型名称 </td>
  </tr>
  <tr>
    <td><strong>JAVA_CLASS </strong></td>
    <td>String =&gt; Java 类名称 </td>
  </tr>
  <tr>
    <td><strong>DATA_TYPE </strong></td>
    <td>short =&gt;在 <code>java.sql.Types</code> 中定义的数值,例如 JAVA_OBJECT </td>
  </tr>
  <tr>
    <td><strong>REMARKS </strong></td>
    <td>String =&gt; 类型的说明性注释 </td>
  </tr>
</table>

<table>
  <tr>
    <td></td>
  </tr>
</table>

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

<p><a name="297585"></a><strong>TYPE_CAT</strong>、<strong>TYPE_SCHEM</strong>、<strong>DATA_TYPE</strong> 
和 <strong>REMARKS</strong> 各列应该是无需加以解释的。<strong>TYPE_NAME</strong> 
实际上就是 SQL 类型名称。在 CREATE TABLE 
语句中就使用该名称来指定这种类型的列。</p>

<p><a name="297586"></a>当 <strong>DATA_TYPE</strong> 是<code>JAVA_OBJECT</code> 
时,则 <strong>JAVA_CLASS </strong>就是与 <strong>TYPE_NAME</strong> 相关联的 
Java 类的全限定的 Java 类名。实际上存储在 <strong>TYPE_NAME</strong> 
列中的所有值必须是该类或其子类的实例。当通过使用 JDBC 
的应用程序从 <strong>TYPE_NAME</strong> 列中取出数值时,将由 JDBC 
驱动程序实现该类或子类的实例。</p>

<p><a name="300789"></a><code>DatabaseMetaData.getUDTs()</code> 方法也接受 SQL 
全限定名作为其第三个参数。这种情况下,将忽略目录和架构模式参数。SQL 
全限定名可能包含通配符。例如,下列代码示例与前一例等同。</p>

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

<blockquote>
  <pre><code>int[] types = {Types.JAVA_OBJECT};
ResultSet rs = dmd.getUDTs(null, null,
	&quot;catalog-name.schema-name.%&quot;, types);
</code>
</pre>
</blockquote>

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

<p>此处,我们假设字符“.”是用来分隔全限定名的各组成元素。请注意全限定名的格式在数据库之间可能会有所不同,所以通常不能象上例一样对全限定名进行硬编码。<code>DatabaseMetaData</code> 
接口提供了有关特定 JDBC 驱动程序所支持的全限定名格式的信息。</p>

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

<h4>7.3.3 检索 Java 类对象</h4>

<p>JDBC 2.0 API 没有为加载 Java 类文件(对应于存储在数据库中的 Java 
对象)提供任何特殊的支持。JDBC 应用程序通过调用 <code>Class.forName()</code> 
并且将类名作为参数传递,可以获得对应于数据库中的对象的类对象。换句话说,JDBC 
2.0 API 假定存储在数据库中的对象的字节码是经由通用 Java 
语言架构加载的。</p>

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

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

<p><br>
</p>

<hr>
<font size="-1"><a href="jdbc2.0.frame.html">

<p>目录</a> | <a href="jdbc2.0.frame6.html">上一页</a> | <a
href="jdbc2.0.frame8.html">下一页</a> </font></p>

<hr>

<address>
  <a href="mailto:jdbc@eng.sun.com">jdbc@eng.sun.com</a> 或 <a
  href="mailto:jdbc-business@eng.sun.com">jdbc-business@eng.sun.com</a> 
</address>
<a href="../../../relnotes/SMICopyright.html"><font size="-1"><i>

<p>版权所有 &copy; 1996, 1997 Sun Microsystems, Inc. 保留所有权利</i></font>。</a><!-- HTML generated by Suzette Pelouch on June 09, 1998 --> 
</p>
</body>
</html>

⌨️ 快捷键说明

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