元数据 API
元数据 API 已经得到更新,DatabaseMetaData 接口现在可以检索 SQL 类型的层次结构,一种新的 ParameterMetaData 接口可以描述 PreparedStatement 对象中参数的类型和属性。
CallableStatements 中已命名的参数
在 JDBC 3.0 之前,设置一个存储过程中的一个参数要指定它的索引值,而不是它的名称。 CallableStatement 接口已经被更新了,现在您可以用名称来指定参数。
数据类型的改变
JDBC 所支持的数据类型作了几个改变,其中之一是增加了两种新的数据类型。
为了便于修改 CLOB(Character Large OBject,字符型巨对象)、BLOB(Binary Large OBject,二进制巨对象)和 REF(SQL 结构)类型的值,同名的数据类型接口都被更新了。接下来的是,因为我们现在能够更新这些数据类型的值,所以 ResultSet 接口也被修改了,以支持对这些数据类型的列的更新,也包括对 ARRAY 类型的更新。
增加的两种新的数据类型是 java.sql.Types.DATALINK 和 java.sql.Types.BOOLEAN。新增的数据类型指的是同名的 SQL 类型。DATALINK 提供对外部资源的访问或 URL,而 BOOLEAN 类型在逻辑上和 BIT 类型是等同的,只是增加了在语义上的含义。DATALINK 列值是通过使用新的 getURL() 方法从 ResultSet 的一个实例中检索到的,而 BOOLEAN 类型是通过使用 getBoolean() 来检索的。
检索自动产生的关键字
为了解决对获取自动产生的或自动增加的关键字的值的需求,JDBC 3.0 API 现在将获取这种值变得很轻松。要确定任何所产生的关键字的值,只要简单地在语句的 execute() 方法中指定一个可选的标记,表示您有兴趣获取产生的值。您感兴趣的程度可以是 Statement.RETURN_GENERATED_KEYS,也可以是 Statement.NO_GENERATED_KEYS。在执行这条语句后,所产生的关键字的值就会通过从 Statement 的实例方法 getGeneratedKeys() 来检索 ResultSet 而获得。ResultSet 包含了每个所产生的关键字的列。清单 1 中的示例创建一个新的作者并返回对应的自动产生的关键字。
连接器关系
大多数应用程序开发人员不需要知道 JDBC 和 J2EE 连结器体系结构之间的关系,就可以很好地使用 JDBC API。但是,由于 JDBC 3.0 规范已经考虑到这项新的体系结构,这使得开发人员能更好地理解 JDBC 在哪里适合 J2EE 标准,以及这个规范的发展方向是什么。
J2EE 连结器体系结构指定了一组协议,允许企业的信息系统以一种可插入的方式连接到应用服务器上。这种体系结构定义了负责与外部系统连接的资源适配器。连接器服务提供者接口(The Connectors Service Provider Interface,SPI)恰好和 JDBC 接口提供的服务紧密配合。
JDBC API 实现了连结器体系结构定义的三个协议中的两个。第一个是将应用程序组件与后端系统相连接的连接管理,它是由 DataSource 和 ConnectionPoolDataSource 接口来实现的。第二个是支持对资源的事务性访问的事务管理,它是由 XADataSource 来处理的。第三个是支持后端系统的安全访问的安全性管理,在这点上,JDBC 规范并没有任何对应点。尽管有最后那个不足,JDBC 接口仍能映射到连接器 SPI 上。如果一个驱动程序厂商将其 JDBC 驱动程序映射到连接器系统协议上,它就可以将其驱动程序部署为资源适配器,并立刻享受可插性、封装和在应用服务器中部署的好处。这样,一个标准的 API 就可以在不同种类的的企业信息系统中,供企业开发人员使用。
ResultSet 可保持性
一个可保持的游标(或结果),就是说该游标在包含它的事务被提交后,也不会自动地关闭。JDBC 3.0 增加了对指定游标可保持性的支持。要制定您 ResultSet 的可保持性,您必须在使用 createStatement()、prepareStatement() 或 prepareCall() 方法准备编写一条语句时就这么做。可保持性可以是下面常量中的一个。
HOLD_CURSORS_OVER_COMMIT
ResultSet 对象(游标)没有被关闭;它们在提交操作得到显式的或隐式的执行以后仍保持打开的状态。
CLOSE_CURSORS_AT_COMMIT
ResultSet 对象(游标)在提交操作得到显式的或隐式的执行后被关闭。
总的来说,在事务提交之后关闭游标操作会带来更好的性能。除非您在事务结束后还需要该游标,否则您最好在执行提交操作后将其关闭。因为规范没有规定 ResultSet 的缺省的可保持性,所以具体行为还将取决于执行情况。然而,我希望在可以使用 JDBC 3.0 驱动程序时,大多数执行在事务结束后仍旧会关闭游标。
返回多重结果
JDBC 2 规范的一个局限是,在任意时刻,返回多重结果的语句只能打开一个 ResultSet。作为 JDBC 3.0 规范中改变的一个部分,规范将允许 Statement 接口支持多重打开的 ResultSets。然而,重要的是 execute() 方法仍然会关闭任何以前 execute() 调用中打开的 ResultSet。所以,要支持多重打开的结果,Statement 接口就要加上一个重载的 getMoreResults() 方法。新式的方法会做一个整数标记,在 getResultSet() 方法被调用时指定前一次打开的 ResultSet 的行为。接口将按如下所示定义标记:
CLOSE_ALL_RESULTS
当调用 getMoreResults() 时,所有以前打开的 ResultSet 对象都将被关闭。
CLOSE_CURRENT_RESULT
当调用 getMoreResults() 时,当前的 ResultSet 对象将被关闭。
KEEP_CURRENT_RESULT
当调用 getMoreResults() 时,当前的 ResultSet 对象将不会被关闭。
连接池
JDBC 3.0 定义了几个标准的连接池属性。开发人员并不需要直接地用 API 去修改这些属性,而是通过应用服务器或数据存储设备来实现。由于开发人员只会间接地被连接池属性的标准化所影响,所以有利之处并不明显。然而,通过减少厂商特定设置的属性的数量并用标准化的属性来代替它们,开发人员能更容易地在不同厂商的 JDBC 驱动程序之间进行交换。另外,这些属性还允许管理员很好地优化连接池,从而使应用程序的性能特点发挥到极致。这些属性如下表所示。
属性名称
描述
maxStatements
连接池可以保持打开的语句数目。
initialPoolSize
当池初始化时可以建立的物理连接的数目。
minPoolSize
池可以包含的物理连接的最小数目。
maxPoolSize
池可以包含的物理连接的最大数目。零指没有最大值。
maxIdleTime
持续时间,以秒计,指一个闲置的物理连接在被关闭前可以在池中停留的时间。零指没有限制。
propertyCycle
间隔时间,以秒计,指连接池在执行其属性策略前可以等待的时间。
预备语句池
除了改进对连接池的支持以外,现在也能缓冲预备语句了。预备语句允许您用一条常用的 SQL 语句然后预编译它,从而在这条语句被多次执行的情况下大幅度地提升性能。在另一个方面,建立一个 PreparedStatement 对象会带来一定量的系统开销。所以,在理想情况下,这条语句的生命周期应该足够长,以补偿它所带来的系统开销。追求性能的开发人员有时候为了延长 PreparedStatement 对象的生命周期会不惜扭曲他们的对象模型。JDBC 3.0 让开发人员不再为此担心,因为数据源层现在负责为预备语句进行缓存。
也许在 JDBC 3.0 中最令人兴奋的附加特点就是 Savepoint 了。JDBC 2 中的事务支持让开发人员可以控制对数据的并发访问,从而保证持续数据总是保持一致的状态。可惜的是,有时候需要的是对事务多一点的控制,而不是在当前的事务中简单地对每一个改变进行回滚。在 JDBC 3.0 下,您就可以通过 Savepoint 获得这种控制。Savepoint 接口允许您将事务分割为各个逻辑断点,以控制有多少事务需要回滚。