由于 SQL 数据类型和 Java 数据类型是不同的,因此需要某种机制在使用 Java 类型的应用程序和使用 SQL 类型的数据库之间来读写数据。
为此,JDBC 提供了 getXXX
和 setXXX
方法集、方法 registerOutParameter
和类 Types
。
JDBC 定义了一个从 JDBC 数据库类型到 Java 类型的标准映射。例如,JDBC 的 INTEGER
类型通常映射为 Java 的 int
类型。这可支持简单的接口,将 JDBC 值读写为简单的 Java 类型。
Java 类型不必与 JDBC 类型完全形同;它们只须能够用足够的类型信息来代表 JDBC 类型,从而能正确地存储和取出参数和从 SQL 语句恢复结果就可以了。例如,Java String
对象可能并不能精确地与任何 JDBC CHAR
类型匹配,但它却可给出足够的类型信息来成功地表示 CHAR
、 VARCHAR
或 LONGVARCHAR
类型。
CHAR、 VARCHAR 和 LONGVARCHAR
JDBC 类型 CHAR
表示固定长度的小字符串,VARCHAR
表示长度可变的小字符串,而 LONGVARCHAR
表示长度可变的大字符串。
与 JDBC CHAR
对应的是 SQL CHAR
类型,所有主要的数据库都支持它。支持长度达 254 个字符,
例如 CHAR(12)
即定义了一个长度为 12 个字符的字符串。
与 JDBC VARCHAR
对应的是 SQL VARCHAR
类型,所有的主要数据库都支持它。支持长度达 254 个字符,当把字符串的值赋给 VARCHAR
变量时,数据库就记住该字符串的长度,使用 SELECT 时,它可以
返回准确的原始字符串。
不幸的是,对于 JDBC LONGVARCHAR
类型,目前并没有一致的 SQL 映射。
CHAR
、VARCHAR
和 LONGVARCHAR
可映射为 String
或 char[]
,但 String
更适合于一般用法。String
类能使 String
和 char[]
之间的转换更为容易:它有一个用于将 String
对象转换为 char[]
的方法,还有一个将 char[]
转换为 String
对象的构造函数。
方法 ResultSet.getString
用于从 CHAR
、VARCHAR
和LONGVARCHAR
域中检索数据。但如果用LONGVARCHAR
储存好几兆字节的字符串时,应将 LONGVARCHAR
值作为 Java 输入流进行检索,之后从流中以任意大小的块来读取数据。使用方法getAsciiStream
和 getUnicodeStream
把储存在 LONGVARCHAR
列的数据作为 Ascii 或 Unicode 字符流来传送。
BINARY、VARBINARY 和 LONGVARBINARY
JDBC 类型BINARY
表示固定长度的小二进制值, VARBINARY
表示长度可变化的小二进制值,而 LONGVARBINARY
表示长度可变化的大二进制值。
不幸的是,这些不同 BINARY
类型的使用还未被标准化,因而在各种主要数据库提供的支持有很大的不同。
在 Java 中,BINARY
、VARBINARY
和 LONGVARBINARY
都可用同一 byte
数组来表示。
检索 BINARY
和 VARBINARY
值时,建议使用 ResultSet.getBytes
。如果类型为 JDBC LONGVARBINARY
的某列储存的是几兆字节长度的字节数组,则建议用方法getBinaryStream
来检索,为 Java 输入流检索,然后可从该流中以更小的块来读取。
JDBC 类型 BIT
代表一个位值,可为 0 或 1。目前只有一部份主流数据库支持它。
JDBC BIT
类型的 Java 映射的推荐类型是 Java 布尔型。
JDBC 类型 TINYINT
代表一个 8 位无符号整数,其值在 0 到 255 之间。 目前只有一部份的数据库支持它。
JDBC 类型SMALLINT
代表一个 16 位的有符号整数,其值在 -32768 和 32767 之间。所有主流数据库所广为支持。
JDBC SMALLINT
类型的 Java 映射的推荐类型是16位的 Java short
类型。
JDBC 类型 INTEGER
代表一个 32 位的有符号整数,其值在 - 2147483648 和 2147483647 之间。所有的主流数据库都至少支持 32 位。
INTEGER
类型 Java 映射的推荐类型是 Java int
类型。
JDBC 类型 BIGINT
代表一个 64 位的有符号整数,其值在 -9223372036854775808 和 9223372036854775807 之间。目前还没有任何数据库实现 SQL BIGINT
类型。
BIGINT
类型的 Java 映射的推荐类型是 Java long 类型。
JDBC 类型 REAL
代表一个有 7 位尾数的“单精度”浮点数。对应的 SQL 类型 REAL
,主流数据库都支持。
REAL
类型的 Java 映射的推荐类型为 Java float
类型。
JDBC 类型 DOUBLE
代表一个有 15 位尾数的“双精度”浮点数。对应的 SQL 类型是 DOUBLE
PRECISION
,主流数据库都支持。
DOUBLE
类型的 Java 映射的推荐类型为 Java double
类型。
JDBC 类型 FLOAT
基本上与DOUBLE
相同,对应的 SQL 类型 FLOAT
。FLOAT
代表一个有 15 位尾数的“双精度”浮点数。同时提供了 FLOAT
和 DOUBLE
,其目的是与以前的 API 实现一致。但这却有可能产生误导。由于 SQL FLOAT
和单精度的 Java float
类型间可能产生混淆,因此建议选用 JDBC DOUBLE
类型而不用 FLOAT
。
FLOAT
类型的 Java 映射的推荐类型为 Java double
类型。
JDBC 类型 DECIMAL
和 NUMERIC
两者非常相似。它们都表示固定精度的十进制值。
相应的 SQL 类型 DECIMAL
和 NUMERIC
,得到广泛支持。这些 SQL 类型都带有精度和比例参数。精度是所支持的十进制数字的总位数,比例是小数点后的数字位数。比例必须永远小于或等于精度。例如,值 "12.345" 有 5 位精度和 3 位比例,而值 ".11" 有 2 位精度和 2 位比例。JDBC 要求所有 DECIMAL
和 NUMERIC
类型都必须支持至少 15 位的精度和比例。
DECIMAL
和 NUMERIC
之间的唯一区别是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
。也可用getString
来检索 DECIMAL
或 NUMERIC
结果,也可用 Java 数值型类型。
有三种 JDBC 类型与时间有关:
DATE
类型表示一个由年、月、日组成的日期。对应的是 SQL DATE
类型,但只有一部份主流数据库实现它。TIME
类型表示一个由小时、分钟和秒组成的时间。对应的是 SQL TIME
类型,但只有一部份主流数据库实现它。TIMESTAMP
类型表示 DATE
加上 TIME
,外加一个纳秒域。对应的 TIMESTAMP
类型,但只有少数几个数据库实现它。 由于标准的 Java 类 java.util.Date
并不与这三个 JDBC 日期—时间类型完全匹配(它含有 DATE
和 TIME
的信息但不含纳秒信息),因此 JDBC 定义了三个 java.util.Date
的子类与 SQL 类型对应。它们是:
java.sql.Date
,对应于 SQL DATE
信息。java.util.Date
基本类中的小时、分钟和秒都设为 0。java.sql.Time
,对应于 SQL TIME
信息。java.util.Date
基本类中的年、月、日域设为 1970 年 1 月 1 日。这是 Java 纪元的“零”日期。java.sql.Timestamp
,对应于 SQL TIMESTAMP
信息。该类扩展了 java.util.Date
,添加了纳秒域。 下述代码段将 java.sql.Timestamp
对象转换为精度达到毫秒量级的 java.util.Date
对象:
Timestamp t = new Timestamp(100, 0, 1, 15, 45, 29, 987245732); java.util.Date d; d = new java.util.Date(t.getTime() + (t.getNanos() / 1000000));
大多数时候,用户要存取的结果和参数其数据类型在编译时是已知的。然而,有些应用程序(例如普通的浏览器或查询工具)在编译时对它们所要存取的数据库的机制并不知晓。
有三种方法和一个常量可用于访问那些在编译时其数据类型尚属未知的值:
ResultSet.getObject
PreparedStatement.setObject
CallableStatement.getObject
java.sql.Types.OTHER
(用作 CallableStatement.registerOutParameter
的一个变量) 例如,如果应用程序想要接受多种类型作为其 ResultSet
对象中的结果,它可以使用 ResultSet.getObject
方法。
ResultSet.getObject
和 CallableStatement.getObject
方法将值检索为 Java Object
。由于 Object
是所有 Java 对象的基本类,因此可将任何 Java 类的实例检索为 Object
的实例。然而,以下 Java 类型是内置的“基本”类型,它们不是类 Object
的实例: boolean
、char
、byte
、short
、int
、long
、 float
和 double
。因此,不能用 getObject
方法来检索它们。然而,这些基本类型每种都有相应的可用作 wrapper 的类。这些类的实例是对象,这意味着可用 ResultSet.getObject
和 CallableStatement.getObject
方法来检索它们。显示了从 JDBC 类型到 Java Object
类型的映射。该表与 JDBC 类型到 Java 类型的标准映射不同:在该表中,除了 JDBC TINYINT
和 JDBC SMALLINT
类型映射为 Java 类Integer
之外,每一个基本的 Java 类型都被替换为它们的 wrapper 类。
方法 getObject
还可用于检索用户定义的 Java 类型。随着抽象数据类型(ADT)和其它用户定义的类型在某些数据库系统中的出现,一些提供者可能会发现用 getObject
来检索这些类型将更方便。
从 JDBC 类型映射到 Java 类型
JDBC 类型 | Java 类型 |
---|---|
CHAR |
String |
VARCHAR |
String |
LONGVARCHAR |
String |
NUMERIC |
java.math.BigDecimal |
DECIMAL |
java.math.BigDecimal |
BIT |
boolean |
TINYINT |
byte |
SMALLINT |
short |
INTEGER |
int |
BIGINT |
long |
REAL |
float |
FLOAT |
double |
DOUBLE |
double |
BINARY |
byte[] |
VARBINARY |
byte[] |
LONGVARBINARY |
byte[] |
DATE |
java.sql.Date |
TIME |
java.sql.Time |
TIMESTAMP |
java.sql.Timestamp |
从 Java 类型映射到 JDBC 类型
Java 类型 | JDBC 类型 |
---|---|
String |
VARCHAR 或 LONGVARCHAR |
java.math.BigDecimal |
NUMERIC |
boolean |
BIT |
byte |
TINYINT |
short |
SMALLINT |
int |
INTEGER |
long |
BIGINT |
float |
REAL |
double |
DOUBLE |
byte[] |
VARBINARY 或 LONGVARBINARY |
java.sql.Date |
DATE |
java.sql.Time |
TIME |
java.sql.Timestamp |
TIMESTAMP |
JDBC 类型 | Java Object 类型 |
---|---|
CHAR |
String |
VARCHAR |
String |
LONGVARCHAR |
String |
NUMERIC |
java.math.BigDecimal |
DECIMAL |
java.math.BigDecimal |
BIT |
Boolean |
TINYINT |
Integer |
SMALLINT |
Integer |
INTEGER |
Integer |
BIGINT |
Long |
REAL |
Float |
FLOAT |
Double |
DOUBLE |
Double |
BINARY |
byte[] |
VARBINARY |
byte[] |
LONGVARBINARY |
byte[] |
DATE |
java.sql.Date |
TIME |
java.sql.Time |
TIMESTAMP |
java.sql.Timestamp |
Java Object 类型 | JDBC 类型 |
---|---|
String |
VARCHAR 或 LONGVARCHAR |
java.math.BigDecimal |
NUMERIC |
Boolean |
BIT |
Integer |
INTEGER |
Long |
BIGINT |
Float |
REAL |
Double |
DOUBLE |
byte[] |
VARBINARY 或 LONGVARBINARY |
java.sql.Date |
DATE |
java.sql.Time |
TIME |
java.sql.Timestamp |
TIMESTAMP |
T I N Y I N T |
S M A L L I N T |
I N T E G E R |
B I G I N T |
R E A L |
F L O A T |
D O U B L E |
D E C I M A L |
N U M E R I C |
B I T |
C H A R |
V A R C H A R |
L O N G V A R C H A R |
B I N A R Y |
V A R B I N A R Y |
L O N G V A R B I N A R Y |
D A T E |
T I M E |
T I M E S T A M P |
|
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
String | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
java.math.BigDecimal | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
Boolean | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
Integer | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
Long | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
Float | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
Double | x | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
byte[] | x | x | x | ||||||||||||||||
java.sql.Date | x | x | x | x | x | ||||||||||||||
java.sql.Time | x | x | x | x | |||||||||||||||
java.sql.Time- stamp | x | x | x | x | x | x |
"x" 表示该方法可以检索 JDBC 类型。"X" 表示建议使用该方法来检索该 JDBC 类型。
T I N Y I N T |
S M A L L I N T |
I N T E G E R |
B I G I N T |
R E A L |
F L O A T |
D O U B L E |
D E C I M A L |
N U M E R I C |
B I T |
C H A R |
V A R C H A R |
L O N G V A R C H A R |
B I N A R Y |
V A R B I N A R Y |
L O N G V A R B I N A R Y |
D A T E |
T I M E |
T I M E S T A M P |
|
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
getByte | X | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
getShort | x | X | x | x | x | x | x | x | x | x | x | x | x | ||||||
getInt | x | x | X | x | x | x | x | x | x | x | x | x | x | ||||||
getLong | x | x | x | X | x | x | x | x | x | x | x | x | x | ||||||
getFloat | x | x | x | x | X | x | x | x | x | x | x | x | x | ||||||
getDouble | x | x | x | x | x | X | X | x | x | x | x | x | x | ||||||
getBigDecimal | x | x | x | x | x | x | x | X | X | x | x | x | x | ||||||
getBoolean | x | x | x | x | x | x | x | x | x | X | x | x | x | ||||||
getString | x | x | x | x | x | x | x | x | x | x | X | X | x | x | x | x | x | x | x |
getBytes | X | X | x | ||||||||||||||||
getDate | x | x | x | X | x | ||||||||||||||
getTime | x | x | x | X | x | ||||||||||||||
getTimestamp | x | x | x | x | X | ||||||||||||||
getAsciiStream | x | x | X | x | x | x | |||||||||||||
getUnicodeStream | x | x | X | x | x | x | |||||||||||||
getBinaryStream | x | x | X | ||||||||||||||||
getObject | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |