第六章 规约

6.1 为了避免歧义,我们将在讨论规约时这些术语:

  • JDBC driver implementation
    JDBC技术驱动的驱动程序及其底层数据源。驱动程序可以为基础数据源未实现的特性提供支持。它还可以提供标准语法/语义和由数据源实现的本机API之间的映射
  • Relevant specifications
    本文档,API规范,以及相关的SQL规范。如果在以上文档中描述了一个特性,那么这也是优先顺序。对JDBC API,它是SQL92加SQL相关的部分:2003,X/Open SQL CLI
  • Supported feature
    JDBC实现支持相关规范中定义的该特性的标准语法和语义的特性。
  • Extension
    没有任何相关规范所涵盖的特性或覆盖的特性的非标准实现。
  • Fully implemented
    用于实现所有方法以支持相关规范中定义的语义的接口的术语。没有一个方法可以抛出异常,因为它们没有实现
  • Must implement
    虽然接口上的某些方法被认为是可选的,但接口是必须实现的。方法不执行必须抛出一个sqlfeaturenotsupportedexception表明相应的功能不支持

6.2 指导规范和要求

以下的准则是 JDBC API 规范要求实现者遵守的基本准则

  • JDBC API 的实现者必须支持 Entry Level SQL92 标准,以及 Drop Table 命令。对 Entry Level SQL92 标准的支持是实现 JDBC API 的最小要求,对于 SQL99 和 SQL2003 特性的实现,必须遵照 SQL99 和 SQL2003 的规范
  • JDBC 驱动必须支持转义语法,转义语法在 第十三章 中有详细解释。
  • JDBC 驱动必须支持事务,参考 第十章。
  • 如果 DatabaseMetaData 的某个方法指明某个特性的可用的,那么驱动必须根据这个特性的相关规范中规定的标准语法实现这个特性,如果该特性需要使用到数据源的原生 API 或者是 SQL 方言,那么由驱动负责实现从标准 SQL 语法到原生 API 或者 SQL 方言的映射关系。如果支持了某个特性,那么 DatabaseMetaData 中与这个特性相关的方法也必须提供实现。比如说,如果一个驱动实现了 RowSet 接口,那么它也应该实现 RowSetMetaData 接口。
  • 驱动必须提供对底层数据源特性的访问方式,包括扩展了 JDBC API 的特性。这么规定的目的是能让使用了 JDBC API 的应用程度能像数据源的原生程序一样,访问与数据源有关的特性。
  • 如果一个 JDBC 驱动不支持,或者部分支持某个可选的数据库特性,那么 DatabaseMetaData 的方法必须指明这个特性还没受到支持,任何还没实现或者还没支持的特性,如果应用程序使用到了,那么应该给应用程序抛一个 SQLFeatureNotSupportedException

注意 —— 根据 SQL92 的规定, JDBC 驱动需要支持 DROP TABLE 命令,不过,是否实现 CASCADE 和 RESTRICT,则是可选的,不是必须的。此外, 当数据源里需要 drop 的表定义了视图、完整性约束时,如何实现 DROP TABLE 来处理这种情况,则每个驱动允许有不同的做法。

6.3 JDBC 4.2 API 要求驱动程序遵守的准则

符合JDBC规范的驱动程序必须执行以下操作:

  • 遵守前一章的指导规范和要求
  • 支持自动加载所有实现了 java.sql.Driver 的驱动类
  • ResultSet 支持 TYPE_FORWARD_ONLY 类型
  • ResultSet 支持 CONCUR_READ_ONLY 并发级别
  • 支持批量更新
  • 完全实现以下接口
    1,java.sql.DatabaseMetaData,
    2,java.sql.ParameterMetaData
    3,java.sql.ResultSetMetaData,
    4,java.sql.Wrapper
  • 必须实现 DataSource 接口,但以下方法是可选的
    1,getParentLogger
  • 除了下列可选方法外,它必须实现 Driver 接口
    1,getParentLogger
  • 必须实现 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
  • 必须实现 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
  • 必须实现 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, 那么必须实现 CallableStatement 接口,但以下方法是可选的
    1,所有的 setXXX, getXXX 方法,以及所有支持命名参数的 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
  • 必须实现 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
  • 如果一个 JDBC 驱动支持 ResultSet 的 CONCUR_UPDATABLE 并发级别,那么必须实现以下方法
    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
  • 如果一个JDBC驱动程序支持的type_scroll_sensitive或type_scroll_insensitive 的 ResultSet类型,下面的ResultSet接口方法必须实现
    1,absolute
    2,afterLast
    3,beforeFirst
    4,first
    5,isAfterLast
    6,isBeforeFirst
    7,isFirst
    8,isLast
    9,last
    10,previous
    11,relative
  • 如果实现了可选接口,则接口上的所有方法也必须完全实现,有以下例外情况
    1,java.sql.SQLInput 和 java.sql.SQLOutput 接口不要求实现 Array, Blob, Clob, NClob, NString, Ref, RowId, SQLXML and URL 这些数据类型

6.4 Java EE 中的 JDBC 规范准则

在 Java EE 环境中使用的 JDBC 驱动,除了必须遵守前文中提到所有规定外,还必须遵守以下规定:

  • 驱动必须支持存储过程,DatabaseMetaData 接口的 supportsStoredProcedures 方法必须返回 true,驱动也需要在调用 Statement, PreparedStatement, and CallableStatement 的方法时,支持转义语法,这些方法是:
    1, executeUpdate
    2, executeQuery
    3, execute

对于存储过程的支持,仅仅需要驱动在调用 Statement, PreparedStatement, and CallableStatement 接口的 execute 方法时,要么返回一个更新数量,要么返回一个单一的 ResultSet 对象。这是因为有些数据库不支持调用存储过程后返回多个 ResultSet 对象。

同时也要支持所有的参数类型,包括 IN, OUT, INOUT

  • 驱动必须支持下面这些函数的转义语法
    ABS
    CONCAT
    LCASE
    LENGTH
    LOCATE (two argument version only)
    LTRIM
    MOD
    RTRIM
    SQRT
    SUBSTRING
    UCASE
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容