第六章 規(guī)約

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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容