6.1 為了避免歧義,我們將在討論規(guī)約時(shí)這些術(shù)語:
- JDBC driver implementation
JDBC技術(shù)驅(qū)動(dòng)的驅(qū)動(dòng)程序及其底層數(shù)據(jù)源。驅(qū)動(dòng)程序可以為基礎(chǔ)數(shù)據(jù)源未實(shí)現(xiàn)的特性提供支持。它還可以提供標(biāo)準(zhǔn)語法/語義和由數(shù)據(jù)源實(shí)現(xiàn)的本機(jī)API之間的映射 - Relevant specifications
本文檔,API規(guī)范,以及相關(guān)的SQL規(guī)范。如果在以上文檔中描述了一個(gè)特性,那么這也是優(yōu)先順序。對(duì)JDBC API,它是SQL92加SQL相關(guān)的部分:2003,X/Open SQL CLI - Supported feature
JDBC實(shí)現(xiàn)支持相關(guān)規(guī)范中定義的該特性的標(biāo)準(zhǔn)語法和語義的特性。 - Extension
沒有任何相關(guān)規(guī)范所涵蓋的特性或覆蓋的特性的非標(biāo)準(zhǔn)實(shí)現(xiàn)。 - Fully implemented
用于實(shí)現(xiàn)所有方法以支持相關(guān)規(guī)范中定義的語義的接口的術(shù)語。沒有一個(gè)方法可以拋出異常,因?yàn)樗鼈儧]有實(shí)現(xiàn) - Must implement
雖然接口上的某些方法被認(rèn)為是可選的,但接口是必須實(shí)現(xiàn)的。方法不執(zhí)行必須拋出一個(gè)sqlfeaturenotsupportedexception表明相應(yīng)的功能不支持
6.2 指導(dǎo)規(guī)范和要求
以下的準(zhǔn)則是 JDBC API 規(guī)范要求實(shí)現(xiàn)者遵守的基本準(zhǔn)則
- JDBC API 的實(shí)現(xiàn)者必須支持 Entry Level SQL92 標(biāo)準(zhǔn),以及 Drop Table 命令。對(duì) Entry Level SQL92 標(biāo)準(zhǔn)的支持是實(shí)現(xiàn) JDBC API 的最小要求,對(duì)于 SQL99 和 SQL2003 特性的實(shí)現(xiàn),必須遵照 SQL99 和 SQL2003 的規(guī)范
- JDBC 驅(qū)動(dòng)必須支持轉(zhuǎn)義語法,轉(zhuǎn)義語法在 第十三章 中有詳細(xì)解釋。
- JDBC 驅(qū)動(dòng)必須支持事務(wù),參考 第十章。
- 如果 DatabaseMetaData 的某個(gè)方法指明某個(gè)特性的可用的,那么驅(qū)動(dòng)必須根據(jù)這個(gè)特性的相關(guān)規(guī)范中規(guī)定的標(biāo)準(zhǔn)語法實(shí)現(xiàn)這個(gè)特性,如果該特性需要使用到數(shù)據(jù)源的原生 API 或者是 SQL 方言,那么由驅(qū)動(dòng)負(fù)責(zé)實(shí)現(xiàn)從標(biāo)準(zhǔn) SQL 語法到原生 API 或者 SQL 方言的映射關(guān)系。如果支持了某個(gè)特性,那么 DatabaseMetaData 中與這個(gè)特性相關(guān)的方法也必須提供實(shí)現(xiàn)。比如說,如果一個(gè)驅(qū)動(dòng)實(shí)現(xiàn)了 RowSet 接口,那么它也應(yīng)該實(shí)現(xiàn) RowSetMetaData 接口。
- 驅(qū)動(dòng)必須提供對(duì)底層數(shù)據(jù)源特性的訪問方式,包括擴(kuò)展了 JDBC API 的特性。這么規(guī)定的目的是能讓使用了 JDBC API 的應(yīng)用程度能像數(shù)據(jù)源的原生程序一樣,訪問與數(shù)據(jù)源有關(guān)的特性。
- 如果一個(gè) JDBC 驅(qū)動(dòng)不支持,或者部分支持某個(gè)可選的數(shù)據(jù)庫特性,那么 DatabaseMetaData 的方法必須指明這個(gè)特性還沒受到支持,任何還沒實(shí)現(xiàn)或者還沒支持的特性,如果應(yīng)用程序使用到了,那么應(yīng)該給應(yīng)用程序拋一個(gè) SQLFeatureNotSupportedException
注意 —— 根據(jù) SQL92 的規(guī)定, JDBC 驅(qū)動(dòng)需要支持 DROP TABLE 命令,不過,是否實(shí)現(xiàn) CASCADE 和 RESTRICT,則是可選的,不是必須的。此外, 當(dāng)數(shù)據(jù)源里需要 drop 的表定義了視圖、完整性約束時(shí),如何實(shí)現(xiàn) DROP TABLE 來處理這種情況,則每個(gè)驅(qū)動(dòng)允許有不同的做法。
6.3 JDBC 4.2 API 要求驅(qū)動(dòng)程序遵守的準(zhǔn)則
符合JDBC規(guī)范的驅(qū)動(dòng)程序必須執(zhí)行以下操作:
- 遵守前一章的指導(dǎo)規(guī)范和要求
- 支持自動(dòng)加載所有實(shí)現(xiàn)了 java.sql.Driver 的驅(qū)動(dòng)類
- ResultSet 支持 TYPE_FORWARD_ONLY 類型
- ResultSet 支持 CONCUR_READ_ONLY 并發(fā)級(jí)別
- 支持批量更新
- 完全實(shí)現(xiàn)以下接口
1,java.sql.DatabaseMetaData,
2,java.sql.ParameterMetaData
3,java.sql.ResultSetMetaData,
4,java.sql.Wrapper - 必須實(shí)現(xiàn) DataSource 接口,但以下方法是可選的
1,getParentLogger - 除了下列可選方法外,它必須實(shí)現(xiàn) Driver 接口
1,getParentLogger - 必須實(shí)現(xiàn) Connection 接口,但以下方法是可選的
1,createArrayOf
2,createBlob,
3,createClob
4,createNClob,
5,createSQLXML
6,createStruct,
7,getNetworkTimeout
8,getTypeMap,
9,setTypeMap
9,prepareStatement(String sql, Statement.RETURN_GENERATED_KEYS),
10,prepareStatement(String sql, int[] columnIndexes)
11,prepareStatement(String sql, String[] columnNames),
12,setSavePoint
13,rollback(java.sql.SavePoint savepoint),
14,releaseSavePoint
15,setNetworkTimeout - 必須實(shí)現(xiàn) Statement 接口,但以下方法是可選的
1,cancel,
2,execute(String sql, Statement.RETURN_GENERATED_KEYS)
3,execute(String sql, int[] columnIndexes),
4,execute(String sql, String[] columnNames)
5,executeUpdate(String sql, Statement.RETURN_GENERATED_KEYS)
6,executeUpdate(String sql, int[] columnIndexes)
7,executeUpdate(String sql, String[] columnNames),
8,getGeneratedKeys
9,getMoreResults(Statement.KEEP_CURRENT_RESULT),除非
10,DatabasemetaData.supportsMultipleOpenResults() 返回 true,否則是可選的。
11,getMoreResults(Statement.CLOSE_ALL_RESULTS) 除非,
12,DatabasemetaData.supportsMultipleOpenResults() 返回 true,否則是可選的。
setCursorName - 必須實(shí)現(xiàn) PreparedStatement 接口,但以下方法是可選的
1,getMetaData,
2,setArray, setBlob, setClob, setNClob, setNCharacterStream, setNString, setRef, setRowId, 3,setSQLXML and setURL,
4,setNull(int parameterIndex,int sqlType, String typeName)
5,setUnicodeStream,
6,setAsciiStream, setBinaryStream, setCharacterStream,
setNCharacterStream - 如果 DatabaseMetaData.supportsStoredProcedures() 返回 true, 那么必須實(shí)現(xiàn) CallableStatement 接口,但以下方法是可選的
1,所有的 setXXX, getXXX 方法,以及所有支持命名參數(shù)的 registerOutputParameter 方法,
2,getArray, getBlob, getClob, getNClob, getNCharacterStream, getNString, getRef, getRowId, 3,getSQLXML and getURL,
4,getBigDecimal(int parameterIndex,int scale)
5,getObject(int i, Class<T> type)
6,getObject(String colName, Class<T> type),
7,getObject(int parameterIndex, java.util.Map<java.lang.String,java.lang.Class<?>> map)
8,registerOutputParam(String parameterName,int sqlType, String typeName),
8,setNull(String parameterName,int sqlType, String typeName)
9,setAsciiStream, setBinaryStream, setCharacterStream, setNCharacterStream - 必須實(shí)現(xiàn) RowSet 接口,但以下方法是可選的
1,所有的 updateXXX 方法,
2,absolute
3,afterLast
4,beforeFirst,
5,cancelRowUpdates,
6,deleteRowfirst,
7,getArray, getBlob, getClob, getNClob, getNCharacterStream, getNString, getRef, getRowId, 8,getSQLXML and getURL,
9,getBigDecimal(int i,int scale)
10,getBigDecimal(String colName,int scale),
11,getCursorName
12,getObject(int i, Class<T> type)
13,getObject(String colName, Class<T> type),
14,getObject(int i, Map<String,Class<?>> map)
15,getObject(String colName, Map<String,Class<?>> map)
16,getRow
17,getUnicodeStream
18,insertRow
19,isAfterLast
20,isBeforeFirst
21,isFirst
22,isLast
23,last
24,moveToCurrentRow
25,moveToInsertRow,
26,previous
27,refreshRow,
28,relative
29,rowDeleted
r30,owInserted,
31,rowUpdated
32,updateRow - 如果一個(gè) JDBC 驅(qū)動(dòng)支持 ResultSet 的 CONCUR_UPDATABLE 并發(fā)級(jí)別,那么必須實(shí)現(xiàn)以下方法
1,除了 updateArray, updateBlob, updateClob, updateNClob, updateNCharacterstream,,
updateNString, updateRef, updateRowId, updateSQLXML, updateURL, updateBlob,
updateClob, updateNClob, updateAsciiStream, updateBinaryStream, updateCharacterStream and updateNCharacterstream 之外的所有 updateXXX 方法。
2,cancelRowUpdates
3,deleteRow
4,rowDeleted
5,rowUpdated
6,updateRow - 如果一個(gè)JDBC驅(qū)動(dòng)程序支持的type_scroll_sensitive或type_scroll_insensitive 的 ResultSet類型,下面的ResultSet接口方法必須實(shí)現(xiàn)
1,absolute
2,afterLast
3,beforeFirst
4,first
5,isAfterLast
6,isBeforeFirst
7,isFirst
8,isLast
9,last
10,previous
11,relative - 如果實(shí)現(xiàn)了可選接口,則接口上的所有方法也必須完全實(shí)現(xiàn),有以下例外情況
1,java.sql.SQLInput 和 java.sql.SQLOutput 接口不要求實(shí)現(xiàn) Array, Blob, Clob, NClob, NString, Ref, RowId, SQLXML and URL 這些數(shù)據(jù)類型
6.4 Java EE 中的 JDBC 規(guī)范準(zhǔn)則
在 Java EE 環(huán)境中使用的 JDBC 驅(qū)動(dòng),除了必須遵守前文中提到所有規(guī)定外,還必須遵守以下規(guī)定:
- 驅(qū)動(dòng)必須支持存儲(chǔ)過程,DatabaseMetaData 接口的 supportsStoredProcedures 方法必須返回 true,驅(qū)動(dòng)也需要在調(diào)用 Statement, PreparedStatement, and CallableStatement 的方法時(shí),支持轉(zhuǎn)義語法,這些方法是:
1, executeUpdate
2, executeQuery
3, execute
對(duì)于存儲(chǔ)過程的支持,僅僅需要驅(qū)動(dòng)在調(diào)用 Statement, PreparedStatement, and CallableStatement 接口的 execute 方法時(shí),要么返回一個(gè)更新數(shù)量,要么返回一個(gè)單一的 ResultSet 對(duì)象。這是因?yàn)橛行?shù)據(jù)庫不支持調(diào)用存儲(chǔ)過程后返回多個(gè) ResultSet 對(duì)象。
同時(shí)也要支持所有的參數(shù)類型,包括 IN, OUT, INOUT
- 驅(qū)動(dòng)必須支持下面這些函數(shù)的轉(zhuǎn)義語法
ABS
CONCAT
LCASE
LENGTH
LOCATE (two argument version only)
LTRIM
MOD
RTRIM
SQRT
SUBSTRING
UCASE