一、数据库类型、JDBC类型和JAVA类型三者关系
答:数据库类型和Java类型是不同的,不同数据库产品所支持的数据类型之间也存在不同(语义或者名称)。因此,要实现Java类型的应用程序与数据库之间的数据通信,需要使用JDBC来处理这种差异,不同的数据库对应不同的JDBC驱动。三者之间的关系如下图所示。
JDBC提供了getXXX和setXXX方法集、ResultSet.updateXXX 、registerOutParameter和Types类等来完成数据类型的映射。如在使用PreparedStatement绑定参数时,采用setXXX方法会绑定参数值与对应类型的oid。当数据库类型为A,而没有使用对应的setXXX方法,且参数值类型与数据库类型在数据库层不能做转换的话,就会报错(JDBC不做类型转换,该工作在数据库层完成)。在获取数据时,使用getXXX方法,如查询数据库返回的结果集ResultSet中,数据类型为JDBC类型,使用JDBC提供的getXXX方法可以进行类型检索,当该getXXX方法与数据类型不匹配时,就会报错。
下表展示了由ResultSet.getXXX方法检索的常见JDBC类型,“x”表示可以检索,“Y”表示建议使用的方法。
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 L 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 |
Y |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x | ||||||
getShort |
x |
Y |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x | ||||||
getInt |
x |
x |
Y |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x | ||||||
getLong |
x |
x |
x |
Y |
x |
x |
x |
x |
x |
x |
x |
x |
x | ||||||
getFloat |
x |
x |
x |
x |
Y |
x |
x |
x |
x |
x |
x |
x |
x | ||||||
getDouble |
x |
x |
x |
x |
x |
Y |
Y |
x |
x |
x |
x |
x |
x | ||||||
getBigDecimal |
x |
x |
x |
x |
x |
x |
x |
Y |
Y |
x |
x |
x |
x | ||||||
getBoolean |
x |
x |
x |
x |
x |
x |
x |
x |
x |
Y |
x |
x |
x | ||||||
getString |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
Y |
Y |
x |
x |
x |
x |
x |
x |
x |
getBytes |
Y |
Y |
x | ||||||||||||||||
getDate |
x |
x |
x |
Y |
x | ||||||||||||||
getTime |
x |
x |
x |
Y |
x | ||||||||||||||
getTimestamp |
x |
x |
x |
x |
Y | ||||||||||||||
getAsciiStream |
x |
x |
Y |
x |
x |
x | |||||||||||||
getUnicodeStream |
x |
x |
Y |
x |
x |
x | |||||||||||||
getBinaryStream |
x |
x |
Y | ||||||||||||||||
getObject |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
二、Oracle数据类型映射表
SQL Datatypes |
JDBC Typecodes |
Standard Java Types |
Oracle Extension Java Types |
CHAR |
java.sql.Types.CHAR |
java.lang.String |
oracle.sql.CHAR |
VARCHAR2 |
java.sql.Types.VARCHAR |
java.lang.String |
oracle.sql.CHAR |
LONG |
java.sql.Types. LONGVARCHAR |
java.lang.String |
oracle.sql.CHAR |
NUMBER |
java.sql.Types.NUMERIC |
java.math. BigDecimal |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.DECIMAL |
java.math. BigDecimal |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.BIT |
boolean |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.TINYINT |
byte |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.SMALLINT |
short |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.INTEGER |
int |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.BIGINT |
long |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.REAL |
float |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.FLOAT |
double |
oracle.sql.NUMBER |
NUMBER |
java.sql.Types.DOUBLE |
double |
oracle.sql.NUMBER |
RAW |
java.sql.Types.BINARY |
byte[] |
oracle.sql.RAW |
RAW |
java.sql.Types. VARBINARY |
byte[] |
oracle.sql.RAW |
LONGRAW |
java.sql.Types. LONGVARBINARY |
byte[] |
oracle.sql.RAW |
DATE |
java.sql.Types.DATE |
java.sql.Date |
oracle.sql.DATE |
DATE |
java.sql.Types.TIME |
java.sql.Time |
oracle.sql.DATE |
TIMESTAMP |
java.sql.Types. TIMESTAMP |
javal.sql.Timestamp |
oracle.sql.TIMESTAMP (see Note) |
BLOB |
java.sql.Types.BLOB |
java.sql.Blob |
oracle.sql.BLOB |
CLOB |
java.sql.Types.CLOB |
java.sql.Clob |
oracle.sql.CLOB |
user-defined object |
java.sql.Types.STRUCT |
java.sql.Struct |
oracle.sql.STRUCT |
user-defined reference |
java.sql.Types.REF |
java.sql.Ref |
oracle.sql.REF |
user-defined collection |
java.sql.Types.ARRAY |
java.sql.Array |
oracle.sql.ARRAY |
BFILE |
oracle.jdbc.OracleTypes. BFILE |
n/a |
oracle.sql.BFILE |
ROWID |
oracle.jdbc.OracleTypes. ROWID |
n/a |
oracle.sql.ROWID |
REF CURSOR type |
oracle.jdbc.OracleTypes. CURSOR |
java.sql.ResultSet |
oracle.jdbc. OracleResultSet |
TIMESTAMP |
oracle.jdbc.OracleTypes. TIMESTAMP |
java.sql.Timestamp |
oracle.sql.TIMESTAMP |
TIMESTAMP WITH TIME ZONE |
oracle.jdbc.OracleTypes. TIMESTAMPTZ |
java.sql.Timestamp |
oracle.sql. TIMESTAMPTZ |
TIMESTAMP WITH LOCAL TIME ZONE |
oracle.jdbc.OracleTypes.TIMESTAMPLTZ |
java.sql.Timestamp |
oracle.sql. TIMESTAMPLTZ |
Oracle公司提供了两个扩展包使JDBC允许访问ORACLE提供的所有数据类型和其特有的性能扩展。
Oracle.sql:包含支持所有Oracle数据库类型的类。使用该包定义的类的对象存储数据值比使用正常JAVA对象的效率要高。
Oracle.jdbc:包含支持访问Oracle数据库的接口。该包支持Oracle.sql的对象读写数据库,其内实现了PreparedStatement和Result等接口。
部分类型释义:
序号 |
数据库 |
JDBC |
JAVA |
1 |
NUMBER |
java.sql.Types.NUMERIC |
java.math.BigDecimal |
Number[(precision[,scale])] p是总位数,1*10-130-1*10126 |
Numeric[p,s] 同number |
可以存储任意精度的数值 | |
2 |
RAW |
Java.sql.Types.binary |
Byte[] |
RAW(size)长度为size的二进制数据 |
Binary(m)允许长度为0-m的定长二进制字符串 |
字节数组 | |
3 |
user-defined reference |
java.sql.Types.REF |
java.sql.Ref |
用户定义的引用 |
引用类型 |
- | |
4 |
BFILE |
oracle.jdbc.OracleTypes. BFILE |
n/a |
Bfile是LOB类型的一种,存放指向操作系统文件的指针,只能只读访问,指向的文件不在数据库中 | |||
5 |
ROWID |
oracle.jdbc.OracleTypes. ROWID |
n/a |
数据库中行的全局唯一地址,包含对象的数据对象编号,该行所在的数据文件中的数据块该行中数据块的位置(第一行是0)数据行所在的数据文件(第一个文件是1) | |||
6 |
TIMESTAMP WITH TIME ZONE |
oracle.jdbc.OracleTypes. TIMESTAMPTZ |
java.sql.Timestamp |
日期和时间 带时区信息的时间格式 |
Oracle扩展实现 |
- | |
7 |
TIMESTAMP WITH LOCAL TIME ZONE |
oracle.jdbc.OracleTypes. TIMESTAMPLTZ |
java.sql.Timestamp |
日期和时间 将时间转换为当地时区对应的时间显示 |
Oracle扩展实现 |
- |
三、PG数据类型映射表
数据库类型 |
PGTypeOid |
JDBC SQL类型 |
Java类型 |
int2 |
21 |
Types.SMALLINT |
java.lang.Integer |
int4 |
23 |
Types.INTEGER |
java.lang.Integer |
oid |
26 |
Types.BIGINT |
java.lang.Long |
int8 |
20 |
Types.BIGINT |
java.lang.Long |
money |
790 |
Types.DOUBLE |
java.lang.Double |
numeric |
1700 |
Types.NUMERIC |
java.math.BigDecimal |
float4 |
700 |
Types.REAL |
java.lang.Float |
float8 |
701 |
Types.DOUBLE |
java.lang.Double |
char |
18 |
Types.CHAR |
java.lang.String |
bpchar |
1042 |
Types.CHAR |
java.lang.String |
varchar |
1043 |
Types.VARCHAR |
java.lang.String |
text |
25 |
Types.VARCHAR |
java.lang.String |
name |
19 |
Types.VARCHAR |
java.lang.String |
bytea |
17 |
Types.BINARY |
[B(byte[]) |
bool |
16 |
Types.BIT |
java.lang.Boolean |
bit |
1560 |
Types.BIT |
java.lang.Boolean |
date |
1082 |
Types.DATE |
java.sql.Date |
time |
1083 |
Types.TIME |
java.sql.Time |
timetz |
1266 |
Types.TIME |
java.sql.Time |
timestamp |
1114 |
Types.TIMESTAMP |
java.sql.Timestamp |
timestamptz |
1184 |
Types.TIMESTAMP |
java.sql.Timestamp |
refcursor |
1790 |
Types.REF_CURSOR |
java.sql.ResultSet |
json |
114 |
Types.OTHER |
org.postgresql.util.PGobject |
point |
600 |
Types.OTHER |
org.postgresql.geometric.PGpoint |
uuid |
2950 |
Types.OTHER |
java.util.UUID |
xml |
142 |
Types.SQLXML |
java.sql.SQLXML |
部分类型释义:
序号 |
数据库 |
JDBC |
JAVA |
1 |
money |
Types.DOUBLE |
java.lang.Double |
货币金额,8bytes |
- |
- | |
2 |
bpchar |
Types.CHAR |
java.lang.String |
一种固定长度的字符类型 |
- |
- | |
3 |
text |
Types.VARCHAR |
java.lang.String |
任意长度字符串,包括纯文本、HTML代码、XML等格式数据 | |||
4 |
json |
Types.OTHER |
org.postgresql.util.PGobject |
存储JavaScript Object Notation数据,也可以用text存储,前者更有利于检查数值是否为可用JSON值 | |||
5 |
point |
Types.OTHER |
org.postgresql.geometric.PGpoint |
几何类型‘点’,(x,y)都是浮点数表示横纵坐标。Lseg(线) , box(长方形)、circle(园)等 |
JDBC中对一些数据库扩展和强化的类型的统一定义类型 |
Pg提供的空间类型‘点’ | |
6 |
uuid |
Types.OTHER |
java.util.UUID |
128位的标识符 在单一数据库中保证唯一 |
- |
- | |
7 |
xml |
Types.SQLXML |
java.sql.SQLXML |
存储xml数据 也可以用text类型存储 |
连接接口提供创建SQLXML对象的方法 |
允许将XML类型映射到java数据类型 |