技术开发 频道

JDBC4.0具有哪些新特性



支持的数据类型

 

本版 JDBC 增加了一些新的数据类型,对其他的一些数据类型,则提供了更好的支持 . 笔者为 XML 被正式支持感到欣喜 , 本版中产生了一个新的接口 : SQLXML . 在笔者看来这个接口值得单独开一个章节为其讨论:

 

SQLXML XML 的支持

 

SQLXML SQL XML 数据类型在 Java 中的表示, XML SQL 中用于表示表中 XML 数据的内建数据类型 . 在默认的情况下, JDBC 驱动将 SQLXML 指针指向 XML 数据而不是数据本身 . SQLXML 对象在其被创建的事务中是稳定的 .

 

在下面的 Example3 类中 , 笔者将说明如何在当前连接中应用 SQLXML 并更新表数据 .

 


public class Example3 { public static void main(String[] args) { ... con = ds.getConnection(); SQLXML sx= con.createSQLXML(); sx.setString("Math is Fun"); String psx ="insert into "+tableName+ " ( id, textbook) values(?,?) "; PreparedStatement pstmt = con.prepareStatement(psx); pstmt.setString(1,"1000"); pstmt.setSQLXML(2,sx); pstmt.executeUpdate(); ... } }

这个例子说明了您所能应用的最简单的情况 . 如果我们继续深入研究,事情就会变得有趣得多了 . 但在我们深入讨论之前 , 让我来告诉您运行 Example3.java . 的结果。 非常不幸 , 我无法获取到 SQLXML 对象,并得到了以下让人失望的输出:

 

java.sql.SQLFeatureNotSupportedException: Feature not

 

   implemented: no details.

 

at org.apache.derby.impl.jdbc.SQLExceptionFactory40.

 

   getSQLException(Unknown Source)

 

... ... ... ...

 

at ex.Example3.main(Example3.java:62)

 

看来 Apache Derby 并没有提供从 Connection 中获取 SQLXML 对象的方法 . 但至少您可以看到笔者正试图在类 Example3 中实现的东西 : 我想插入一行新的数据: id 列值为 1000 textbook (S QLXML 类型 ) 插入 Math is Fun .

 

笔者用如下代码段结束关于 SQLXML 的讨论,这段代码从数据库中读取 XML 值并将其转化为 Document 对象 .

 

SQLXML sqlxml = rs.getSQLXML(column);

 

InputStream binaryStream = sqlxml.getBinaryStream();

 

DocumentBuilder parser =

 

  DocumentBuilderFactory.newInstance().newDocumentBuilder();

 

Document doc = parser.parse(binaryStream);

 

可以把一个列的值直接转化为 XML 文档不是一件令人兴奋的事情吗 ? 我觉得这个特性非常好 .

 

ROWID 数据类型

 

SQL ROWID 唯一标识了数据表中的一行,并是访问该行的最快的方法, 本版增加了 RowId 接口以提供对 ROWID SQL 数据类型在 Java 类中的支持 .

 

对大对象类型支持的增强

 

JDBC 版本 2 提供了对大的 SQL 对象如: CLOB , BLOB , ARRAY 的支持 , 及用于添加相关接口的 Struct: Clob , Blob , Array , and Struct . 在本版的 JDBC 中增加了很多对这些对象访问的新方法 . 笔者将在 API 变化一节中进行详细论述 .

 

支持 National Character Set NCS 转化

 

SQL:2003 提出了如下 SQL 数据类型的支持: NCHAR , NVARCHAR , LONGNVARCHAR , NCLOB . 其功用和 CHAR , VARCHAR , LONGVARCHAR , CLOB 类似 ,其区别仅是,这些类型的文本是用 NCS 编码的。 如果需要大量的字符处理,您可能更倾向于 NCS 数据类型而非普通的数据类型。本版 JDBC 提供了增强对 NCS 支持的 API.

 

  • PreparedStatement , CallableStatement , ResultSet 接口中增加了一些 setter updater 方法以支持 NCS 转化 . 比如方法 setNString , setNCharacterStream , setNClob 等等 .

     

  • SQLInput and SQLOutput 接口中增加了读写方法以支持 t NClob NString 对象 .

API 变化

 

JDBC 4.0 最大的变化来自于 API, 笔者在本小节对其做简单介绍 .

 

Array

 

Array 接口增加了一个 free 方法来释放 array 对象及其持有的资源 .

 

Connection PooledConnection

 

Connection 接口现在提供一系列创建大对象的方法如 createClob , createBlob 等等 . 此外还有 getter setter 对客户端信息的重载方法 , 及验证当前连接正确性的方法 .

 

PooledConnection 接口当前提供 addStatementEventListener removeStatementEventListener 两个方法来注册和注销 StatementEventListener 接口 , 这个接口是在本版 JDBC 中新引入的 . 这个接口的一个实例将获取到 S tatement 池中 PreparedStatement s 的变化 . 比如,在注册以后 , 当驱动调用 statementClosed 方法时,所有 StatementEventListener 将获得 statement 已关闭的通知 .

 

DatabaseMetaData

 

不同的关系数据库往往支持不同的特性 , 并通过不同的方法来实现这些特性 , 并可能会是用不同的数据类型 . 这将会导致移植性的问题,因为根据实现的不同,无法保证代码在所有关系数据库上都能正确执行 . 这样的问题在一定程度上可以通过这个接口所获得的信息来解决 . 比如,如果您在写一个通过传入 SQL 语句来建立表的代码 . 您可能想知道在 CREATE TABLE 语句中有哪些数据类型是可用的,此时可以调用该接口中的 getTypeInfo 方法 .

 

本版 JDBC 增加了一些获取信息的方法 . Example4 , 我将通过一段代码展示如何获得满足某种模式的数据库结构的列表。 .

 

 

con = ds.getConnection();

 

DatabaseMetaData dmd = con.getMetaData();

 

rs=dmd.getSchemas("TABLE_CAT", "SYS%");

 

//iterate over the rs and print to console

 

 

首先通过调用 dmd.getCatalogs 并遍历结果集 , 得到了唯一的一个值: TABLE_CAT . 接着通过调用 rs=dmd.getSchemas("TABLE_CAT", "SYS%") 得到以 SYS 开头的数据库和表结构 . 以下是笔者得到的结果 :

 

 

SYS

 

SYSCAT

 

SYSCS_DIAG

 

SYSCS_UTIL

 

SYSFUN

 

SYSIBM

 

SYSPROC

 

SYSSTAT

 

 

Scalar 函数支持

 

一个 scalar 函数操作预定义的输入数据集合并返回结果 . 比如: scalar 函数调用 ABS(number) 返回 number 的绝对值 . 这些 scalar 函数可以作为 SQL 字符串的一部分来使用 . 本版 JDBC 要求当所依赖的关系数据库支持以下功能时: CHAR_LENGTH , CHARACTER_LENGTH , CURRENT_DATE , CURRENT_TIME , CURRENT_TIMESTAMP , EXTRACT , OCTET_LENGTH , POSITION ,驱动必须实现这些功能。

 

Statement , PreparedStatement , CallableStatement

 

Statement 接口当前提供 isClosed 方法来判断 statement 是否已关闭 , setPoolable 用来设置是否可以被池化 , isPoolable 来检测当前的池化状态。

 

PreparedStatement CallableStatement 接口现在提供了更多插入大对象的方法 , 通过使用 InputStream Reader .

 

Wrapper

 

这个版本的 API 增加了一个新的 Wrapper 接口, 来提供一种访问资源的实例的方法 , 这可能是基于架构的考虑 . Wrapper 模式 , 被许多的 JDBC 驱动实现应用以提供 JDBC API 之外的依赖于具体数据源的应用 . 这个接口的主要目的是用来提供供应商相关的功能。您可以通过调用 unwrap 方法来获取到数据库连接的接口实现的实例 . 因为这是一个重量级的操作 , 在使用前,应该先调用 isWrapperFor 方法来检测是否当前实例是某种实现的一个间接或直接的 Wapper

 

能够给出一个程序例子当然是最好的,但是 Apache Derby 参考手册 l 指出 : "JDBC 4.0 引入了 wrapped JDBC 对象的概念 ... 对于 Derby 来说 , 这对 Derby 来说是没有意义的,因为 Derby 并不做规范之外的扩展 ." 因此看来这种尝试也就变得无甚必要了 !

 

结论

 

我们已经分为 4 类讨论了 JDBC 4.0 所做的一些改进和新的特性,这些新特性增加了编程易用性,提高了生产率 . 尽管 API 规范已经推出几个月了 , 到笔者截稿时,主流的数据库厂商都没有提供本版的 JDBC 驱动 . 当更多的供应商开始支持 JDBC 4.0 当然也包括您所中意的那个 您就可以享受 JDBC4.0 所提供的这些易用的功能了 .

 

最后,我认为有一个各大数据库厂商的支持的 JDBC 版本的列表是必要的 . Sun Developer Network (SDN) 上有一个 JDBC Data Access API http://developers.sun.com/product/jdbc/drivers 页提供了一份更新不太及时的列表 .

0