Java.sql.Types,數據庫字段類型,java數據類型的對應關係

如下轉自:http://kummy.itpub.net/post/17165/172850 本文在原文基礎上有增減。html


本概述是從《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference》這本書中摘引來的。JavaSoft 目前正在準備這本書。這本書是一本教程,同時也是 JDBC 的重要參考手冊,它將做爲 Java 系列的組成部份,在 1997 年春季由 Addison-Wesley 出版公司出版。java

8.1 概述

因爲 SQL 數據類型和 Java 數據類型是不一樣的,所以須要某種機制在使用 Java 類型的應用程序和使用 SQL 類型的數據庫之間來讀寫數據。程序員

爲此,JDBC 提供了 getXXX 和 setXXX 方法集、方法 registerOutParameter 和類 Typessql

本章聚集了影響各類類和接口的數據類型的有關信息,並列出全部的對應關係表(這些表顯示了 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 類型在某個特定的數據庫中的行爲的確切定義,咱們建議查閱一下數據庫文檔。app

若是想要編寫一種可在各類數據庫上建立表的可移植 JDBC 程序,用戶主要有兩個選擇。第一個選擇是:限制本身只使用那些被廣爲接受的 SQL 類型名稱(例如 INTEGERNUMERIC 或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 類型 CHARVARCHAR 和 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 程序員沒必要區分 CHARVARCHAR 和 LONGVARCHAR 這三種類型的 JDBC 字符串。它們均可表示爲 Java String,而且在不知道所須要的確切數據類型時也可正確讀寫 SQL 語句。

CHARVARCHAR 和 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 對象。咱們建議用它來從 CHARVARCHAR 和LONGVARCHAR 域中檢索數據。它適用於檢索普通的數據,但若是用 JDBC 類型LONGVARCHAR 來儲存多個兆字節的字符串時,用它進行檢索將顯得十分笨拙。爲此,ResultSet 接口中有兩個方法可供程序員將 LONGVARCHAR 值做爲 Java 輸入流進行檢索,以後可從該流中以任意大小的塊來讀取數據。這兩個方法是:getAsciiStream 和 getUnicodeStream,它們將把儲存在 LONGVARCHAR 列的數據做爲 Ascii 或 Unicode 字符流來傳送。

8.3.2 BINARY、VARBINARY 和 LONGVARBINARY

JDBC 類型 BINARYVARBINARY 和 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 中,BINARYVARBINARY 和 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 的精度留給實現去決定。但事實上,全部支持 DOUBLEPRECISION 類型的主流數據庫都支持至少 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 DATE 類型,其定義由 SQL-92 給出,但只有一部份主流數據庫實現它。某些數據庫提供了另一些支持相似語義的 SQL 類型。
  • JDBC TIME 類型表示一個由小時、分鐘和秒組成的時間。對應的是 SQL TIME 類型,其定義由 SQL-92 給出,但只有一部份主流數據庫實現它。與 DATE 同樣,某些數據庫提供了另一些支持相似語義的 SQL 類型。
  • JDBC TIMESTAMP 類型表示 DATE 加上 TIME,外加一個納秒域。對應的 TIMESTAMP 類型,其定義由 SQL-92 給出,但只有少數幾個數據庫實現它。

因爲標準的 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,添加了納秒域。

全部這三個與時間有關的 JDBC 類都是 java.util.Date 的子類,所以它們可用在任何可使用 java.util.Date 的地方。例如,國際化 (internationalization) 方法將 java.util.Date 對象用做變量,所以可將這三個與時間有關的 JDBC 類中任何一個的實例做爲參數傳給國際化方法。

JDBC Timestamp 對象除了具備其父類的日期和時間成份外,還有一個獨立的納秒組件。若是將 java.sql.Timestamp 對象用於須要 java.util.Date 對象的地方,則納秒組件將丟失。但因爲是以毫秒的精度來儲存 java.util.Date 對象的,所以將 java.sql.Timestamp 對象轉換爲 java.util.Date 對象時能夠保持這樣的精度。這可經過將納秒組件中的納秒轉換爲毫秒(用納秒數除以 1,000,000)並將之添到 java.util.Date 對象中來實現。轉換中可能丟失高達 999,999 納秒,但所產生的 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));

8.4 映射示例

任何狀況下,當 Java 程序要從數據庫中檢索數據時,必須存在某種形式的映射和數據轉換。大多數時候, JDBC 程序員將在知道其目標數據庫機制的狀況下進行編程。例如,他們將知道數據庫含有哪些表、表中每一列的數據類型。所以,他們可以使用 ResultSet、 PreparedStatement和 CallableStatement 接口中那些與類型有關的存取方法。本節給出三個示例,描述各類情形中所要求的數據映射和轉換。

8.4.1 簡單的 SQL 語句

在最多見的情形中,用戶將執行簡單的 SQL 語句,而後取回含有結果的 ResultSet 對象。由數據庫返回並存放在 ResultSet 列的值,其類型爲 JDBC 數據類型。調用ResultSet.getXXX 方法將把該值檢索爲 Java 數據類型。例如,若是某個 ResultSet 列含有一個 JDBC FLOAT 值,則方法 getDouble 將把它檢索爲 Java double 類型。8.6.6 節所示的表顯示了哪些 getXXX 方法可檢索哪些 JDBC 類型(若是用戶不知道某個 ResultSet 列的類型,可經過調用 ResultSet.getMetaData 方法來得到有關信息,而後再調用ResultSetMetaData 的 getColumnType 或 getColumnTypeName 方法)。如下代碼段示範瞭如何得到結果中各列的類型名稱:

    String query = "select * from Table1";
    ResultSet rs = stmt.executeQuery(query);
    ResultSetMetaData rsmd = rs.getMetaData();
    int columnCount = rsmd.getColumnCount();
    for (int i = 1; i <= columnCount; i++)  {
      String s = rsmd.getColumnTypeName(i);
      System.out.println ("Column " + i + " is type " + s);
    }

8.4.2 帶 IN 參數的 SQL 語句

在另外一個可能的狀況中,用戶將發送帶輸入參數的 SQL 語句。這種狀況下,用戶經過調用 PreparedStatement.setXXX 方法爲每一個輸入參數賦值。例如,PreparedStatement.setLong(1, 2345678) 將把值 2345678 做爲 Java 的 long 類型賦給第一個參數。爲了將 2345678 到數據庫中,驅動程序將把它轉換爲 JDBC BIGINT。驅動程序將把哪一種 JDBC 類型送到數據庫中是由 Java 類型到 JDBC 類型的標準映射所決定的

8.4.3 帶 OUT 參數的 SQL 語句

還有一個狀況是,用戶要調用已存儲過程,將值賦給其 INOUT 參數,從結果中檢索值,而後從參數中檢索值。這種情形極爲少見且至關複雜,但它卻不失爲映射和數據轉換的好範例。

這種狀況下,首先要作的是用 PreparedStatement.setXXX 方法對 INOUT 參數賦值。此外,因爲這些參數同時也用於輸出,所以程序員必須爲每一個參數註冊 JDBC 類型,該類型是數據庫所要返回給該參數的值的 JDBC 類型。這可用 CallableStatement.registerOutParameter 方法來完成,後者接受在類 Types 中所定義的 JDBC 類型做爲其變量。程序員能夠用ResultSet.getXXX 方法系列來檢索返回給ResultSet 對象的結果,用 CallableStatement.getXXX 方法系列來檢索存放在輸出參數中的值。

用於 ResultSet.getXXX 方法的 XXX 類型在某些狀況下很是靈活。8.6.6 節中所示的表顯示了哪些 ResultSet.getXXX 方法可用於檢索哪些 JDBC 類型。

用於 CallableStatement.getXXX 方法的 XXX 類型必須映射爲那個參數所註冊的 JDBC 類型。例如,若是數據庫應返回類型爲 JDBC REAL 的輸出值,則該參數應被註冊爲java.sql.Types.REAL。所以,要檢索該 JDBC REAL 值,必須調用 CallableStatement.getFloat 方法(從 JDBC 類型到 Java 類型的映射在 8.6.1 節中的表中給出)。方法 getFloat先把儲存在輸出參數中的值從 JDBC REAL 類型轉換爲 Java float 類型,而後將它返回。爲了適應各類數據庫和使應用程序具備更高的可移植性,建議先檢索 ResultSet 對象中的值,再檢索輸出參數中的值。

下述代碼示範的是調用名爲 getTestData 的已存儲過程。它有兩個參數,且都是 INOUT 參數。首先, Connection 對象 con 將建立 CallableStatement 對象 cstmt。而後,方法setByte 把第一個參數設置爲 Java byte 類型,其值爲 25。驅動程序將把 25 轉換爲 JDBC TINYINT 類型並將之送到數據庫中。方法 setBigDecimal 用輸入值 83.75 來設置第二個參數。驅動程序將把這個 java.math.BigDecimal 對象轉換爲 JDBC NUMERIC 值。接下來將這兩個參數註冊爲 OUT 參數,第一個參數註冊爲 JDBC TINYINT 類型,第二個參數註冊爲小數點後面帶兩位數字的 JDBC DECIMAL 類型。執行 cstmt 後,就用 ResultSet.getXXX 方法將值從 ResultSet 對象中檢索出來。方法 getString 將第一列中的值做爲 Java String 對象獲取,getInt 將第二列中的值做爲 Java int 獲取,getInt 將第三列中的值做爲 Java int 獲取。

以後, CallableStatement.getXXX 方法檢索存放在輸出參數中的值。方法 getByte 將 JDBC TINYINT 檢索爲 Java bytegetBigDecimal 將 JDBC DECIMAL 檢索爲小數點後面帶有兩位數字的 java.math.BigDecimal 對象。注意,當參數既是輸入參數同時又是輸出參數時,setXXX 方法所用的 Java 類型與 getXXX 方法所用的相同(正如 setByte 和 getByte 中同樣)。registerOutParameter 方法將它註冊成由 Java 類型映射來的 JDBC 類型(Java byte 類型映射爲 JDBC TINYINT,如 8.6.2 節中的表所示)。

    CallableStatement cstmt = con.prepareCall(
          "{call getTestData(?, ?)}");
    cstmt.setByte(1, 25);
    cstmt.setBigDecimal(2, 83.75);
    // 將第一個參數註冊爲 JDBC TINYINT,第二個
    // 參數註冊爲小數點後面帶有兩位數字的 JDBC DECIMAL 類型
    cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
    cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 2);
    ResultSet rs = cstmt.executeUpdate();
    // 檢索並打印結果中的值。
    while(rs.next()) {
      String name = rs.getString(1);
      int score = rs.getInt(2);
      int percentile = rs.getInt(3);
      System.out.print("name = " + name + ", score = " + score + ", "
      System.out.println("percentile = " + percentile);
    // 檢索輸出參數中的值 
    byte x = cstmt.getByte(1);
    java.math.BigDecimal n = cstmt.getBigDecimal(2, 2);

總之,CallableStatement.getXXX 和 PreparedStatement.setXXX 方法系列中的 XXX 是 Java 類型。對於 setXXX 方法,驅動程序先把 Java 類型轉換爲 JDBC 類型,再把它送到數據庫中(使用 8.6.2 節中的表所示的標準映射)。對於 getXXX 方法, 驅動程序先把數據庫返回的 JDBC 類型轉換爲 Java 類型(用 8.6.1 節表中所示的標準映射),再把它返回給 getXXX 方法。

registerOutParameter 方法只接受 JDBC 類型的變量,而 setObject 方法卻可接受 JDBC 類型的變量。

注意,若是在可選的第三個變量的位置上提供了 JDBC 類型,則 setObject 方法將把參數值從 Java 類型顯式地轉換爲所指定的 JDBC 類型。若是沒有爲 setObject 提供目標 JDBC 類型,則將把參數值轉換爲 Java 類型的標準映射 JDBC 類型(如 8.6.2 節的表中所示)。在將參數送到數據庫中以前,驅動程序都要進行顯式或隱式轉換。

8.5 動態數據存取

大多數時候,用戶要存取的結果和參數其數據類型在編譯時是已知的。然而,有些應用程序(例如普通的瀏覽器或查詢工具)在編譯時對它們所要存取的數據庫的機制並不知曉。所以,JDBC 除了支持靜態數據類型存取外,還支持類型徹底動態肯定的數據存取。

有三種方法和一個常量可用於訪問那些在編譯時其數據類型尚屬未知的值:

  • 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 的實例: booleancharbyteshortintlong、 float 和 double。所以,不能用 getObject 方法來檢索它們。然而,這些基本類型每種都有相應的可用做 wrapper 的類。這些類的實例是對象,這意味着可用 ResultSet.getObject 和 CallableStatement.getObject 方法來檢索它們。第 67 頁中的表 8.6.3 顯示了從 JDBC 類型到 Java Object 類型的映射。該表與 JDBC 類型到 Java 類型的標準映射不一樣:在該表中,除了 JDBC TINYINT 和 JDBC SMALLINT 類型映射爲 Java 類Integer 以外,每個基本的 Java 類型都被替換爲它們的 wrapper 類。

方法 getObject 還可用於檢索用戶定義的 Java 類型。隨着抽象數據類型(ADT)和其它用戶定義的類型在某些數據庫系統中的出現,一些提供者可能會發現用 getObject 來檢索這些類型將更方便。

8.6 數據類型映射表

本節含有如下表,它們是 JDBC 類型 和 Java 數據類型之間的映射關係表:

8.6.1 節 — 從 JDBC 類型映射到 Java 類型

8.6.2 節 — 從 Java 類型映射到 JDBC 類型

8.6.3 節 ─ 從 JDBC 類型映射到 Java Object 類型

8.6.4 節 ─ 從 Java Object 類型映射到 JDBC 類型

8.6.5 節 ─ 由 setObject 所進行的轉換

8.6.6 節 — 由 ResultSet.getXXX 方法所檢索的 JDBC 類型

8.6.1 從 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


 

8.6.2 從 Java 類型映射到 JDBC 類型

該表顯示的是表 8.6.1 的反映射: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


 String 類型的映射一般是 VARCHAR,但若是所給的值超出了驅動程序對 VARCHAR 值所限定的極限,則將轉換爲 LONGVARCHAR 類型。對 byte[]VARBINARY 及 LONGVARBINARY 值也同樣。

8.6.3 從 JDBC 類型到 Java Object 類型的映射

因爲 Java 內置類型(例如 boolean 和 int)不是 Object 的子類型,所以對於 getObject/setObject 方法,從 JDBC 類型到 Java object 類型的映射稍有不一樣。此種映射以下表所示:

 

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


  

8.6.4 Java Object 類型映射到 JDBC 類型

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


 注意,String 的映射一般爲 VARCHAR,但若是所給的值超出了驅動程序對 VARCHAR 值所限定的極限值,則將轉換爲 LONGVARCHAR。對 byte[]VARBINARY 和 LONGVARBINARY 值也同樣。

 

8.6.5 由 setObject 所進行的轉換

setObject

 

  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


 從 Java object 類型到 JDBC 類型的轉換。

 

8.6.6 由 ResultSet.getXXX 方法檢索的 JDBC 類型

"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
相關文章
相關標籤/搜索