SQL 数据类型和 Java 数据类型间的映射关系(转)

 

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

为此,JDBC 提供了 getXXX 和 setXXX 方法集、方法 registerOutParameter 和类 Types。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

不幸的是,这些不同 BINARY 类型的使用还未被标准化,因而在各种主要数据库提供的支持有很大的不同。

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

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

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

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

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

8.3.3 BIT
JDBC 类型 BIT 代表一个位值,可为 0 或 1。

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

JDBC BIT 类型的 Java 映射的推荐类型是 Java 布尔型。

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

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

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

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

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

JDBC SMALLINT 类型的 Java 映射的推荐类型是 Java short 类型。

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

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

INTEGER 类型 Java 映射的推荐类型是 Java int 类型。

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

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

BIGINT 类型的 Java 映射的推荐类型是 Java long 类型。

8.3.8 REAL
JDBC 类型 REAL 代表一个有 7 位尾数的“单精度”浮点数。

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

REAL 类型的 Java 映射的推荐类型为 Java float 类型。

8.3.9 DOUBLE
JDBC 类型 DOUBLE 代表一个有 15 位尾数的“双精度”浮点数。

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

DOUBLE 类型的 Java 映射的推荐类型为 Java double 类型。

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

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

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

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

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

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

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

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

8.3.12 DATE、TIME 和 TIMESTAMP
有三种 JDBC 类型与时间有关:

JDBC DATE 类型表示一个由年、月、日组成的日期。对应的是 SQL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle的数据类型: 1、CHAR数据类型,该类型是固定长度的字符串,如果没指定大小,则默认占用一字节,如果输入的值小于指定的长度,则数据库用空格填充至固定长度,如果用户输入的值大于指定的长度,则数据库返回错误信息 2、varchar2,用于存储可变长度的字符串,使用该数据类型可节省磁盘空,但存储效率没有CHAR高 3、NCHAR和nvarchar2,NCHAR和CHAR区别在于NCHAR用来存储Unicode字符集类型,即双字节字符数据,CHAR是一个字节,而NCAHR是一个字符(两个字节),前者是CHAR(1)无法插入‘的’,后者是NCHAR(1)可以插入‘的’ 4、NUMBER表示数值数据类型,NUMBER(P,S),P为精度,表示数据的总位数,S为范围,表示小数点右边数字的位数 5、DATE数据类型,使用7个字节固定长度,每个字节分别存储世纪,年,月,日 ,时,分,秒,ORACLE中SYSDATE函数的功能是返回当前的日期和时 6、TIMESTAMP数据类型,和DATE相似,但是这个类型的秒精确到小数点后6位,而DATE没有秒的小数部分 7、LOB数据类型用于存储大型的,没有被结构化的数据,例如二进制文件,图片文件,LOB主要分为BLOB和CLOB,BLOB数据类型用于存储二进制对象:图像,音频,视频...CLOB数据类型用于存储字符格式的大型对象 8、ORACLE其实也支持INTEGER,FLOAT,DOUBLE,VARCHAR,最好用ORACLE自身的NUMBER 和 VARCHAR2

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值