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

📄 mapping.doc.html

📁 JDBC入门中文文档
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!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="introTOC.doc.html">目录</a> | <a
    href="callablestatement.doc.html">上一页</a> | <a href="SimpleSelect.doc.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="996857"></a> </p>

<h1>8 - 映射 SQL 和 Java 类型</h1>

<p>本概述是从《<em>JDBC<font size="-1"><sup>TM</sup></font> Database Access from 
Java<font size="-1"><sup>TM</sup></font>: A Tutorial and Annotated Reference</em>》这本书中摘引来的。JavaSoft 
目前正在准备这本书。这本书是一本教程,同时也是 JDBC 
的重要参考手册,它将作为 Java 系列的组成部份,在 1997 年春季由 
Addison-Wesley 出版公司出版。</p>

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

<h2>8.1&nbsp; 概述</h2>

<p>由于 SQL 数据类型和 Java 
数据类型是不同的,因此需要某种机制在使用 Java 
类型的应用程序和使用 SQL 类型的数据库之间来读写数据。</p>

<p><a name="1006428"></a>为此,JDBC 提供了 <code>getXXX</code> 和 <code>setXXX</code> 
方法集、方法 <code>registerOutParameter</code> 和类 <code>Types</code>。</p>

<p><a name="1006429"></a>本章汇集了影响各种类和接口的数据类型的有关信息,并列出所有的对应关系表(这些表显示了 
SQL 类型和 Java 类型之间的映射关系)以便于参考。</p>

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

<h2>8.2&nbsp; 将 SQL 数据类型映射为 Java 类型</h2>

<p>不幸的是,不同数据库产品所支持的 SQL 
类型之间有很大的不同。即使不同的数据库以相同的语义支持 SQL 
类型,它们也可能用不同的名称。例如,绝大多数的主流数据库都支持一种表示大型二进制值的 
SQL 类型,但 Oracle 把这种类型叫做 <code>LONG RAW</code>,Sybase 把它叫做 <code>IMAGE</code>,Informix 
却把它叫做 <code>BYTE</code>,而 DB2 又把它叫做 <code>LONG VARCHAR FOR BIT 
DATA</code>。</p>

<p>幸运的是,JDBC 
程序员通常并不需要自己去关心目标数据库所用的实际 SQL 
类型的名称。大多数时候,JDBC 
程序员将根据一些现有的数据库表来进行编程。他们无须关心用于创建这些表的确切 
SQL 类型的名称。</p>

<p><a name="1008144"></a>JDBC 在 <code>java.sql.Types</code> 
类中定义了一系列的常规 SQL 
类型标识符。这些类型可用于表示那些最为常用的 SQL 类型。在用 
JDBC API 编程时,程序员通常可以使用这些 JDBC 类型来引用一般的 SQL 
类型,而无须关心目标数据库所用的确切 SQL 
类型的名称。在下一节中将对这些 JDBC 类型进行仔细说明。</p>

<p><a name="1008145"></a>程序员用到 SQL 类型名称的主要地方是在用 SQL 的 <code>CREATE 
TABLE </code>语句创建新的数据库表时。这种情况下,程序员必须注意应该使用目标数据库所支持的 
SQL 类型名称。如果需要知道各种 SQL 
类型在某个特定的数据库中的行为的确切定义,我们建议查阅一下数据库文档。</p>

<p><a name="1008149"></a>如果想要编写一种可在各种数据库上创建表的可移植 
JDBC 
程序,用户主要有两个选择。第一个选择是:限制自己只使用那些被广为接受的 
SQL 类型名称(例如 <code>INTEGER</code>、<code>NUMERIC</code> 或 <code>VARCHAR</code>)。这些类型有可能能适应所有的数据库。第二个选择是:用 
<code>java.sql.DatabaseMetaData.getTypeInfo</code> 
方法来找出给定的数据库实际上支持哪些 SQL 类型,然后选择与给定 
JDBC 类型相匹配的特定于数据库的 SQL 类型名。</p>

<p><a name="1008156"></a>JDBC 定义了一个从 JDBC 数据库类型到 Java 
类型的标准映射。例如,JDBC 的 <code>INTEGER</code> 类型通常映射为 Java 
的 <code>int</code> 类型。这可支持简单的接口,将 JDBC 值读写为简单的 
Java 类型。</p>

<p><a name="1008157"></a>Java 类型不必与 JDBC 
类型完全形同;它们只须能够用足够的类型信息来代表 JDBC 
类型,从而能正确地存储和取出参数和从 SQL 
语句恢复结果就可以了。例如,Java <code>String</code> 
对象可能并不能精确地与任何 JDBC <code>CHAR</code> 
类型匹配,但它却可给出足够的类型信息来成功地表示 <code>CHAR</code>、 
<code>VARCHAR</code> 或 <code>LONGVARCHAR</code> 类型。</p>

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

<h2>8.3&nbsp; JDBC 类型</h2>

<p>本节描述各种 JDBC 数据类型及其与标准 SQL 类型和 Java 
类型的关联方式。</p>

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

<h3>8.3.1 CHAR、 VARCHAR 和 LONGVARCHAR</h3>

<p>JDBC 类型 <code>CHAR</code>、<code>VARCHAR</code> 和 <code>LONGVARCHAR</code> 
密切相关。<code>CHAR</code> 表示固定长度的小字符串,<code>VARCHAR</code> 
表示长度可变的小字符串,而 <code>LONGVARCHAR</code> 
表示长度可变的大字符串。</p>

<p><a name="1008162"></a>与 JDBC <code>CHAR</code> 对应的是 SQL <code>CHAR</code> 
类型,其定义由 SQL-92 
给出,且所有主要的数据库都支持它。它接受用于指定字符串最大长度的参数,例如 
<code>CHAR(12)</code> 即定义了一个长度为 12 
个字符的字符串。所有主要的数据库都支持长度达 254 个字符的 <code>CHAR</code>。</p>

<p><a name="1008163"></a>与 JDBC <code>VARCHAR</code> 对应的是 SQL <code>VARCHAR</code> 
类型,其定义由 SQL-92 
给出,且所有的主要数据库都支持它。它接受用于指定字符串最大长度的参数,例如 
<code>VARCHAR(12)</code> 即定义了一个最大长度为 12 
个字符的字符串。所有主要数据库都至少支持长度达 254 个字符的 <code>VARCHAR</code>。当把字符串的值赋给 
<code>VARCHAR</code> 变量时,数据库就记住该字符串的长度,使用 <code>SELECT 
时,它可以</code>返回准确的原始字符串。</p>

<p><a name="1008164"></a>不幸的是,对于 JDBC <code>LONGVARCHAR</code> 
类型,目前并没有一致的 SQL 
映射。所有主要数据库都支持某种类型的长度可变的大字符串,这种字符串支持高达十亿位字节的数据,但 
SQL 类型名称却变化多样。</p>

<p><a name="1008168"></a>Java 程序员不必区分 <code>CHAR</code>、<code>VARCHAR</code> 
和 <code>LONGVARCHAR</code> 这三种类型的 JDBC 字符串。它们都可表示为 
Java <code>String</code>,并且在不知道所需要的确切数据类型时也可正确读写 
SQL 语句。</p>

<p><a name="1008169"></a><code>CHAR</code>、<code>VARCHAR</code> 和 <code>LONGVARCHAR</code> 
可映射为 <code>String</code> 或 <code>char[]</code>,但 <code>String</code> 
更适合于一般用法。同时, <code>String</code> 类能使 <code>String</code> 和 
<code>char[]</code> 之间的转换更为容易:它有一个用于将 <code>String</code> 
对象转换为 <code>char[]</code> 的方法,还有一个将<code> char[]</code> 
转换为 <code>String</code> 对象的构造函数。</p>

<p><a name="1008170"></a>必须提及的一个问题是:如何处理类型为 <code>CHAR(n)</code> 
的固定长度的 SQL 字符串。答案是 JDBC 驱动程序(或 DBMS)将用适当的空格来进行填补。因此,当从数据库中检索 
<code>CHAR(n)</code> 域时,驱动程序将把它转换为长度为 <code>n</code> 的 
Java <code>String</code> 
对象,对象末尾可能含有一些填补空格。反之,当把 <code>String</code> 
对象送到某个 <code>CHAR(n)</code> 域时,驱动程序和/或数据库将在字符串的末尾填上一些必要的空格,使字符串的长度达到 
<code>n</code>。</p>

<p><a name="1008171"></a>方法 <code>ResultSet.getString</code> 
用于分配和返回新的 <code>String</code> 对象。我们建议用它来从 <code>CHAR</code>、<code>VARCHAR</code> 
和<code>LONGVARCHAR</code> 
域中检索数据。它适用于检索普通的数据,但如果用 JDBC 类型 <code>LONGVARCHAR</code> 
来储存多个兆字节的字符串时,用它进行检索将显得十分笨拙。为此,<code>ResultSet</code> 
接口中有两个方法可供程序员将 <code>LONGVARCHAR</code> 值作为 Java 
输入流进行检索,之后可从该流中以任意大小的块来读取数据。这两个方法是<code>:getAsciiStream</code> 
和 <code>getUnicodeStream</code>,它们将把储存在 <code>LONGVARCHAR</code> 
列的数据作为 Ascii 或 Unicode 字符流来传送。</p>

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

<h3>8.3.2 BINARY、VARBINARY 和 LONGVARBINARY</h3>

<p>JDBC 类型 <code>BINARY</code>、<code>VARBINARY</code> 和 <code>LONGVARBINARY</code> 
密切相关。<code>BINARY</code> 表示固定长度的小二进制值, <code>VARBINARY</code> 
表示长度可变化的小二进制值,而 <code>LONGVARBINARY</code> 
表示长度可变化的大二进制值。</p>

<p><a name="1008191"></a>不幸的是,这些不同 <code>BINARY</code> 
类型的使用还未被标准化,因而在各种主要数据库提供的支持有很大的不同。</p>

<p><a name="1008192"></a>对应于 JDBC <code>BINARY</code> 类型的 SQL <code>BINARY</code> 
类型,是一种非标准的 SQL 
扩展,只在某些数据库上才实现。它接受用于指定二进制字节数的参数。例如,<code>BINARY(12)</code> 
即定义了一个长度为 12 个字节的 binary 类型。通常,<code>BINARY </code>值被限定在 
254 个字节以内。</p>

<p><a name="1008193"></a>对应于 JDBC <code>VARBINARY</code> 类型的 SQL <code>VARBINARY</code> 
类型,是一种非标准的 SQL 
扩展,只在某些数据库上才实现。它接受用于指定二进制字节最大数的参数。例如,<code>VARBINARY(12)</code> 
即定义了一个长度最大可为 12 个字节的二进制类型。通常,<code>VARBINARY</code> 
的值被限定在 254 个字节以内。当把二进制的值赋给 <code>VARBINARY</code> 
变量时,数据库就记住这个所赋值的长度,调用 <code>SELECT</code> 
时,它返回准确的原始值。</p>

<p><a name="1008194"></a>遗憾的是,目前还没有一致的 SQL 类型名称与 JDBC <code>LONGVARBINARY</code> 
类型相对应。所有主要数据库都支持某种类型的长度可变的大二进制类型,它可支持高达十亿个字节的数据,但 
SQL 类型名称却变化多样。</p>

<p><a name="1008198"></a>在 Java 中,<code>BINARY</code>、<code>VARBINARY</code> 和 <code>LONGVARBINARY</code> 
都可用同一 <code>byte</code> 数组来表示。由于可在不知道所需的 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 确切 <code>BINARY</code> 
数据类型的情况下正确地读写 SQL 语句,因此,Java 
程序员无需区分它们。</p>

<p>检索 <code>BINARY</code> 和 <code>VARBINARY</code> 值时,我们建议使用 <code>ResultSet.getBytes</code>。然而,如果类型为 
JDBC <code>LONGVARBINARY</code> 
的某列储存的是几兆字节长度的字节数组,则建议用方法 <code>getBinaryStream</code> 
来检索。与 <code>LONGVARCHAR</code> 的情形类似,该方法可以使 Java 
程序员将 <code>LONGVARBINARY</code> 值作为 Java 
输入流检索,然后可从该流中以更小的块来读取。</p>

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

<h3>8.3.3&nbsp; BIT</h3>

<p>JDBC 类型 <code>BIT</code> 代表一个位值,可为 0 或 1。</p>

<p><a name="1008202"></a>SQL-92 定义了 SQL <code>BIT</code> 类型。但与 JDBC <code>BIT</code> 
类型不同,这种 SQL-92 BIT 
类型带参数,用于定义固定长度的二进制字符串。幸运的是,SQL-92 
也允许用简单的非参数化的 <code>BIT</code> 
类型来代表单个的二进制数字。这种用法对应于 JDBC <code>BIT</code> 
类型。不幸的是,SQL-92 <code>BIT</code> 类型只有在 “完全” SQL-92 
中才要求,且目前只有一部份主流数据库支持它。因此,可移植的代码也许宁愿用 
JDBC <code>SMALLINT</code> 类型,这种类型已得到广泛支持。</p>

<p><a name="1008203"></a>JDBC <code>BIT</code> 类型的 Java 映射的推荐类型是 
Java 布尔型。</p>

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

<h3>8.3.4 TINYINT</h3>

<p>JDBC 类型 <code>TINYINT</code> 代表一个 8 位无符号整数,其值在 0 到 
255 之间。</p>

<p><a name="1008206"></a>对应的 SQL 类型 <code>TINYINT</code> 
目前只有一部份的数据库支持它。因此,可移植的代码也许宁愿用 
JDBC <code>SMALLINT</code> 类型,这种类型已得到广泛支持。</p>

<p><a name="1008207"></a>JDBC <code>TINYINT</code> 类型的 Java 映射的推荐类型是 
Java <code>byte</code> 或 Java <code>short</code>。8 位的 Java <code>byte</code> 
类型代表一个有符号的整数,其值在 -128 到 127 之间,因此对于大的 <code>TINYINT</code> 
值它并非总合适,而 16 位的 Java <code>short</code> 
类型却总能存储所有的 <code>TINYINT</code> 值。</p>

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

<h3>8.3.5 SMALLINT</h3>

<p>JDBC 类型 <code>SMALLINT</code> 代表一个 16 位的有符号整数,其值在 
-32768 和 32767 之间。</p>

<p><a name="1008210"></a>对应的 SQL 类型 <code>SMALLINT</code>,其定义由 SQL- 92 
给出,并为所有主流数据库所支持。SQL-92 标准将 <code>SMALLINT</code> 
的精度留给实现去决定。但事实上,所有的主流数据库都至少支持 16 
位。</p>

<p><a name="1008211"></a>JDBC <code>SMALLINT</code> 类型的 Java 
映射的推荐类型是 Java <code>short</code> 类型。</p>

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

<h3>8.3.6 INTEGER</h3>

<p>JDBC 类型 <code>INTEGER</code> 代表一个 32 位的有符号整数,其值在 - 
2147483648 和 2147483647 之间。</p>

<p><a name="1008214"></a>对应的 SQL 类型 <code>INTEGER</code>,其定义由 SQL- 92 
给出,并为所有主流数据库所广为支持。SQL-92 标准将 <code>INTEGER</code> 
的精度留给实现去决定。但事实上,所有的主流数据库都至少支持 32 
位。</p>

<p><a name="1008215"></a><code>INTEGER</code> 类型 Java 映射的推荐类型是 Java <code>int</code> 
类型。</p>

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

<h3>8.3.7 BIGINT</h3>

<p>JDBC 类型 <code>BIGINT</code> 代表一个 64 位的有符号整数,其值在 
-9223372036854775808 和 9223372036854775807 之间。</p>

<p><a name="1008218"></a>对应的 SQL 类型 <code>BIGINT</code> 是 SQL 
的一个非标准扩展。事实上,目前还没有任何数据库实现 SQL <code>BIGINT</code> 
类型。我们建议在可移植的代码中避免使用该类型。</p>

<p><a name="1008219"></a><code>BIGINT</code> 类型的 Java 映射的推荐类型是 Java 
long 类型。</p>

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

<h3>8.3.8 REAL</h3>

<p>JDBC 类型 <code>REAL</code> 代表一个有 7 位尾数的“单精度”浮点数。</p>

<p><a name="1008222"></a>对应的 SQL 类型 <code>REAL</code>,其定义由 SQL- 92 
给出。虽然未得到普遍支持,但在主流数据库中却已得到广泛支持。SQL-92 
标准将 <code>REAL</code> 
的精度留给实现去决定。但事实上,所有的支持 <code>REAL</code> 
类型的主流数据库都支持至少 7 位数的尾数精度。</p>

<p><a name="1008223"></a><code>REAL</code> 类型的 Java 映射的推荐类型为 Java <code>float</code> 
类型。</p>

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

<h3>8.3.9 DOUBLE</h3>

<p>JDBC 类型 <code>DOUBLE</code> 代表一个有 15 
位尾数的“双精度”浮点数。</p>

<p><a name="1008226"></a>对应的 SQL 类型是 <code>DOUBLE</code> <code>PRECISION</code>,其定义由 
SQL- 92 给出,并为主流数据库所广为支持。SQL-92 标准将 <code>DOUBLE</code> 
<code>PRECISION</code> 的精度留给实现去决定。但事实上,所有支持 <code>DOUBLE</code> 
<code>PRECISION</code> 类型的主流数据库都支持至少 15 位数的尾数精度。</p>

<p><a name="1008227"></a><code>DOUBLE</code> 类型的 Java 映射的推荐类型为 Java <code>double</code> 
类型。</p>

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

<h3>8.3.10 FLOAT</h3>

<p>JDBC 类型 <code>FLOAT</code> 基本上与 JDBC 类型 <code>DOUBLE</code> 
相同。我们同时提供了 <code>FLOAT</code> 和 <code>DOUBLE</code>,其目的是与以前的 
API 实现一致。但这却有可能产生误导。<code>FLOAT</code> 代表一个有 15 
位尾数的“双精度”浮点数。</p>

<p><a name="1008230"></a>对应的 SQL 类型 <code>FLOAT</code>,其定义由 SQL-92 
给出。SQL-92 标准将 <code>FLOAT</code> 
的精度留给实现去决定。但事实上,所有支持 <code>FLOAT</code> 
类型的主流数据库都支持至少 15 位数的尾数精度。</p>

<p><a name="1008231"></a><code>FLOAT</code> 类型的 Java 映射的推荐类型为 Java <code>double</code> 
类型。然而,由于 SQL <code>FLOAT</code> 和单精度的 Java <code>float</code>类型间可能产生混淆,因此建议 
JDBC 程序员通常选用 JDBC <code>DOUBLE</code> 类型而不选用 <code>FLOAT</code>。</p>

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

<h3>8.3.11 DECIMAL 和 NUMERIC</h3>

<p>JDBC 类型 <code>DECIMAL</code> 和 <code>NUMERIC</code> 
两者非常相似。它们都表示固定精度的十进制值。</p>

<p><a name="1008234"></a>相应的 SQL 类型 <code>DECIMAL</code> 和 <code>NUMERIC</code>,其定义在 
SQL-92 中给出,并得到广泛支持。这些 SQL 
类型都带有精度和比例参数。精度是所支持的十进制数字的总位数,比例是小数点后的数字位数。比例必须永远小于或等于精度。例如,值 
&quot;12.345&quot; 有 5 位精度和 3 位比例,而值 &quot;.11&quot; 有 2 
位精度和 2 位比例。JDBC 要求所有 <code>DECIMAL</code> 和 <code>NUMERIC</code> 
类型都必须支持至少 15 位的精度和比例。</p>

<p><a name="1008235"></a><code>DECIMAL</code> 和 <code>NUMERIC</code> 
之间的唯一区别是 SQL-92 规范要求 <code>NUMERIC</code> 
类型必须以确切指定的精度来表示,而对<code> DECIMAL</code> 
类型,它允许实现在创建该类型时所指定的精度以外再添加额外的精度。因此,创建为类型 
<code>NUMERIC(12,4)</code> 的列将总是用 12 位数来表示,而创建为类型 <code>DECIMAL(12,4)</code> 
的列则可用更大的位数来表示。</p>

<p><a name="1008236"></a><code>DECIMAL</code> 和 <code>NUMERIC</code> 类型的 Java 
映射的推荐类型是<code> java.math.BigDecimal</code>,该 Java 
类型也用绝对精度来表示定点数。<code>java.math.BigDecimal</code> 
类型提供了一些数学操作,可对 <code>BigDecimal</code> 类型与其它的 <code>BigDecimal</code> 
类型、整数类型和浮点数类型进行加、减、乘、除的运算。</p>

<p><a name="1008237"></a>用于检索 <code>DECIMAL</code> 和 <code>NUMERIC</code> 
值的推荐方法是 <code>ResultSet.getBigDecimal</code>。JDBC 还允许将这些 SQL 
类型作为简单的 <code>Strings</code> 或 <code>char</code> 
数组来访问。因此,Java 程序员可用 <code>getString</code> 来检索 <code>DECIMAL</code> 
或 <code>NUMERIC</code> 结果。然而,这将使常见的用 <code>DECIMAL</code> 或 <code>NUMERIC</code> 
来表示的货币值变得极为尴尬,因为它意味着应用程序编程人员必须对字符串进行数学运算。当然,也可将这些 
SQL 类型作为 Java 数值型类型来检索。</p>

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

<h3>8.3.12 DATE、TIME 和 TIMESTAMP</h3>

<p>有三种 JDBC 类型与时间有关: 

<ul>
  <p><a name="1008240"></a></p>
  <li>JDBC <code>DATE</code> 
    类型表示一个由年、月、日组成的日期。对应的是 SQL <code>DATE </code>类型,其定义由 
    SQL-92 
    给出,但只有一部份主流数据库实现它。某些数据库提供了另外一些支持类似语义的 
    SQL 类型。<br>
    <br>
    <a name="1008241"></a> </li>
  <li>JDBC <code>TIME</code> 
    类型表示一个由小时、分钟和秒组成的时间。对应的是 SQL <code>TIME</code> 
    类型,其定义由 SQL-92 给出,但只有一部份主流数据库实现它。与 <code>DATE</code> 
    一样,某些数据库提供了另外一些支持类似语义的 SQL 类型。<br>
    <br>
    <a name="1008242"></a> </li>
  <li>JDBC <code>TIMESTAMP</code> 类型表示 <code>DATE</code> 加上 <code>TIME</code>,外加一个纳秒域。对应的 
    <code>TIMESTAMP </code>类型,其定义由 SQL-92 
    给出,但只有少数几个数据库实现它。<br>
    <br>
  </li>
</ul>

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

<p>由于标准的 Java 类 <code>java.util.Date</code> 并不与这三个 JDBC 
日期—时间类型完全匹配(它含有<code> DATE</code> 和 <code>TIME</code> 
的信息但不含纳秒信息),因此 JDBC 定义了三个 <code>java.util.Date</code> 
的子类与 SQL 类型对应。它们是: 

<ul>
  <p><a name="1008244"></a></p>

⌨️ 快捷键说明

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