您现在的位置:中国下载站学院中心网络编程JAVA教程JAVA实例教程 → 文章列表

探讨JDBC 4.0在设计和性能方面的改进

作者:佚名  来源:不详  发布时间:2007-4-13 17:40:08   

减小字体 增大字体

 
 

  摘要 JDBC(Java数据库连接)4.0预计在2006年中期作为Java 6.0标准版的一部分正式发行。现在,我们大家都关心的问题是,如何利用这一新的规范来改进Java应用程序数据存取和交互方面的设计与性能。本文将与你一起探讨JDBC 4.0中引入的新特征,讨论它对一些现有问题的解决方案,并且通过具体示例展示它在设计和性能方面的改进。

  自从核心Java语言的第一个公开发行版本起,JDBC(Java数据库连接)已经经历了十年的发展历程。它的当前版本4.0(将与Java标准版本6.0一起打包发行)提供了一组更为丰富的API,主要目的在于改进软件开发的设计和性能。

  本文将重点讨论JDBC 4.0规范在设计和性能方面的改进。

  一、 注释和泛型DataSet

  在本文中,我假定你已经了解注释和泛型。其实,这两个概念是随着J2SE 5.0的发行一同引入的;与此同时,JDBC 4.0中引入了注释和泛型DataSet。这一变化的主要目的是为了简化SQL查询和SQL DML(数据操纵语言)语句的执行。

  新一代API定义了一组Query和DataSet接口。这个Query接口定义了一组带有JDBC注释的方法。这些带有注释的方法描述了SQL select和update语句,并且指定应该如何把结果绑定到一个DataSet上。这个DataSet接口是一个通过泛型定义实现的参数化类型,也为结果集数据提供一种类型安全的定义。

  所有的Query接口都继承自BaseQuery接口。你可以使用Connection.createQueryObject()或DataSource.createQueryObject()方法(这两个方法都使用一个Query接口类型作为它的参数)来具体实现这样的接口。

  一个DataSet接口继承自java.util.List;该接口使用一个描述结果集数据列的数据库(该数据库是通过Query接口的一个注释的方法返回的)作为它的参数类型。在连接方式和非连接方式下都可以操作和使用DataSet。因此,根据使用的是连接方式还是非连接方式,这个DataSet也分别相应地实现为一个ResultSet或CachedRowSet。DataSet,作为java.util.List的一个子接口,允许使用Iterator模式通过java.util.Iterator接口存取其数据行。

  你可以用两种方式来指定数据类或用户定义类(作为DataSet接口的一个参数类型)-作为一个结构或作为一个JavaBeans对象。无论哪一种方式都能够把结果集数据列绑定到用户定义的类定义上;但是,JavaBeans组件模型更漂亮些,并且更利于对象定义在另外的支持JavaBeans模型的框架中的重用。

  列表1摘自本文示例中的代码片断,它展示了如何使用这种新型的API来创建和运行SQL查询:使用一个用户定义类定义结果集数据,并且把返回的结果集绑定到用户定义的描述中。

  列表1.Employee用户定义类型与employeeQueries接口

pubic class Employee {
 private int employeeId;
 private String firstName;
 private String lastName;
 public int getEmployeeId() {
  return employeeId;
 }
 public setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }
 public String getFirstName() {
  return firstName;
 }
 public setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public setLastName(String lastName) {
  this.lastName = lastName;
 }
}
interface EmployeeQueries extends BaseQuery {
 @Select (sql="SELECT employeeId, firstName, lastName FROM employee")
 DataSet<Employee> getAllEmployees ();
 @Update (sql="delete from employee")
 int deleteAllEmployees ();
}
Connection con = ...
EmployeeQueries empQueries = con.createQueryObject (EmployeeQueries.class);
DataSet<Employee> empData = empQueries.getAllEmployees ();

  二、 改进异常处理能力

  在JDBC API 4.0以前的版本中,异常处理功能极其有限。对于所有类型的错误都会笼统地抛出一个SQLException异常-根本不存在异常的详细分类,且没有相应的层次定义。所以这时,你唯一能够得到一些有意义的信息的办法是检索和分析SQLState值。另一方面,SQLState值及其相应的含义会因不同的数据源而有所改变;因此,要想追踪到问题的"根部"并且有效地处理异常是一件非常乏味的任务。

  JDBC 4.0改进了异常处理能力,同时也缓解了一些前面提到的问题。其中的关键改进有:

  · 把SQLException分成短暂异常和非短暂异常两种类型

  · 支持链式异常

  · 实现Iterable接口

  当一个以前失败的操作检索成功时,将会抛出SQLTransientException异常;而在检索不成功时将会抛出SQLNonTransientException异常-除非导致SQLException的原因得到纠正。

  图1展示了子类SQLTransientException和SQLNonTransientException。

  
图1.SQL异常类型:短暂型和非短暂型

  另一方面,在新的API中,加入了对链式异常的支持。新的异常基类构造器中添加了额外参数以捕获异常的可能原因。例如,在一个循环中可能存在SQLException遍历;这时,开发人员可以调用getCause()来决定异常的可能原因。如果获取的结果的确是产生这些异常的原因,那么getCause()方法能够返回一个非SQLException。

  现在,SQLException类实现了Iterable接口并且支持J2SE 5.0的for each循环。

  列表2描述了新的for-each-loop结构的用法:

  列表2.For each循环结构

catch(SQLException ex) {
 for(Throwable t : ex) {
  System.out.println("exception:" + t);
 }
}

  三、 支持XML数据类型

  如今,大量的数据行以XML格式存在。通过在SQL 2003规范中定义了一种标准XML类型,现在大多数数据库都已提供对XML数据类型的支持。通过加入这样一种数据类型,一个XML数据集或文档可能成为一个数据库表中的一行的一个字段或列值。在JDBC 4.0以前,也许在JDBC框架内操作这样的数据的最好的方法是使用来自于驱动程序供应商的专利扩展产品或作为一种CLOB类型来存取它。

  现在,JDBC 4.0把SQLXML定义为映射数据库SQL XML类型的Java数据类型。这种API支持把一个XML类型作为一个字符串或作为一个StAX流进行处理。Streaming API for XML(在JSR 173规范中确立)基于Iterator模式,它与基于Observer模式的Simple API for XML Processing(SAX)形成对照。

  调用Connection对象的createSQLXML()方法就能够创建一个SQLXML对象。开始时这是一个空对象;因此,通过使用setString()方法或createXMLStreamWriter()方法把一个XML流关联到该对象可以把数据依附到其上。同样,XML数据可以从一个SQLXML对象中进行检索,这是通过使用getString()或createXMLStreamReader()方法把一个XML流与该对象关联实现的。

  ResultSet,PreparedStatement和CallableStatement接口中都提供了getSQLXML()方法用于检索SQLXML数据类型。另外,PreparedStatement和CallableStatement中还引入了setSQLXML()方法用于把SQLXML对象作为参数添加。

  当对象在长时间运行的事务中保持有效时,可以通过调用上面这些接口的free()方法来释放SQLXML资源;事实证明这是一种比较适当的方法。另外,开发者可以在一个数据源上调用DatabaseMetaData的getTypeInfo()方法来检查数据库是否支持SQLXML数据类型,因为这个方法能够返回它支持的所有数据类型。

  四、 改进Connection接口

  Connection接口定义也得到了增强,用于更高效地分析连接状态。

  有时数据库连接是不可用的,尽管可能不必关闭这些连接并对之进行垃圾回收。处于这样的情况下,数据库常常表现出速度缓慢且不具有响应性。此时,在大多数情况下,重新初始化该连接也许是解决这种问题的唯一方法。在JDBC 4.0以前版本时,没有办法来区分一个旧连接和一个已经关闭的连接;而新式API则在Connection接口中添加了一个isValid()方法用来查询是否连接仍然有效。

  另外,数据库连接经常在客户端被共享;并且有时,一些客户使用的资源比另一些客户多,这可能会导致一种"饥饿"现象。为此,Connection接口中定义了一个setClientInfo()方法以定义客户端特定的属性,这可以被客户端用于分析和监控资源利用情况。

  五、 有关RowId方面的改进

  在许多数据库中,RowId都被用作唯一标识一个表中行的方法。在查询条件中使用RowId往往是检索数据的最快方法,特别是在Oracle和DB2数据库情况下。现在,既然java.sql.RowId是一种内嵌的Java类型;那么,你就可以充分利用与其用法相关的性能优点。当表中存在重复的数据并且一些行数据相同时,RowId是标识唯一行的最有效的方法。然而,还要注意到,RowId在一个表中是唯一的,而对于整个数据库来说并非如此;它们可能发生变化并且不为所有数据库所支持。典型情况下,RowId不是跨数据源可移植的;因此,当使用多种数据源时应该慎重。

  在数据源定义的生命周期内,只要一行未被删除,那么该行相应的RowId就一直保持有效。我们可以调用DatabaseMetadata.getRowIdLifetime()方法来决定RowId的生命周期。这个方法的返回类型是一个枚举类型。现在,把所有这些枚举类型总结到如下的表格中。


在百度中搜索更多探讨JDBC 4.0在设计和性能方面的改进相关网页转贴于:中国下载站

  • 上一篇文章:Hibernate程序性能优化的考虑要点
  • 下一篇文章:基于JDBC的数据库连接池技术研究与设计
  • 阅读统计:[]
  • 中国下载站】【设为主页】【收藏本页】【打印本文】【回到顶部】【关闭此页

    相关文章
    文章评论(评论内容只代表网友观点,与本站立场无关!)
    RowIdLifetime枚举类型定义
    ROWID_UNSUPPORTED 数据源不支持RowId类型

    用户名: 查看更多评论

    分 值:100分 85分 70分 55分 40分 25分 10分 0分

    内 容:

             (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码


    设为首页 - 关于我们 - 广告服务 - 网站地图 - 加入收藏 - 网站声明 - 网站帮助 - 友情链接

    • Copyright (C) 2006-2008 www.cndownz.com All Rights Reserved.
      中国下载站 版权所有. 粤ICP备05141802号. 对本站有任何建议、意见或投诉,请来信:cndownzcom@yahoo.com.cn.
      喜欢中国下载站(cndownz.com),请把中国下载站(cndownz.com)告诉你QQ上的5位好友,多谢支持!