体验 JDBC 2.0 规范的一些新东西

[来源] 达内    [编辑] 达内   [时间]2013-02-16

从数据源取得数据后, RowSet对象可以断开于数据源的连接,这使得该对象很小(如果数据量特别不大). rowset也可以序列化. 所以rowset很小并可以序列化, 一个断开连接的rowset是传送数据给瘦客户机的理想工具

  JDBC 2.0 API 包括两个package:

  1. java.sql 为JDBC 2.0的核心包,其中包括了JDBC 1.0规范中规定的API和新的核心API,这个包包含于Java 2 Standard Edition中.

  2. javax.sql 为JDBC 2.0的标准扩展包,相对与JDBC 1.0而言是全新的,这个包包含于Java 2 Enterprise Edition中.

  ★ 采用了新的方法连接数据库 DataSource Interface

  JDBC 2.0 提供了新的接口DataSource用来实现数据库连接,可以替代1.0中提供的DriverManager类。好处是:

  ☆ 增强了代码的可移植性

  ☆ 方便了代码的维护

  一个DataSource对象代表一个实际的数据源。这个数据源可以是从关系数据库到表格形式的文件,完全依赖于它是怎样实现的.一个数据源对象注册到JNDI名字服务后,应用程序就可以从JNDI服务器上取得该对象,并使用之和数据源建立连接.

  数据源及如何装入的信息(名字,地址,端口等等)以Properties的形式保存在DataSource对象中.这样就增强了应用程序的可移植性,因为程序中不需要像使用DriverManager那样给出硬性的驱动器名字(往往包含了特定厂商的名字). 这种做法还增强了代码的可维护性,比如数据源移植到另一台服务器上后, 所需要作的就是更新一下相关的property,使用数据源的代码更不不必改动.

  系统管理员或者有相应权限的人实现DataSource对象. DataSource对象的实现需要设置对象的properties并把它注册到JNDI名字服务器上, 这些活动可能会用特定工具来实现. 系统管理员用一个逻辑名字对应DataSource对象,这个名字可是是任意的. 在下面的例子中DataSource对象的名字是InventoryDB. 依照传统习惯, DataSource对象的名字包含在jdbc下, 所以这个数据源对象的完整名字是:jdbc/InventoryDB.

  实现数据源对象后, 应用程序员就可以使用它来建立和数据源之间的连接了. 下面的代码片断演示了通过这种方式获得连接. 上面两行使用了JNDI API获得DataSource对象,第三行代码使用JDBC API获得连接:

  Context ctx = new InitialContext();

  DataSource ds = (DataSource) ctx.lookup("jdbc/InventoryDB"):

  Connection conn = ds.getConnection("password","username");

  DataSource对象中获得的的Connection对象和用DriverManager.getConnection方法获得的对象是等同的. 由于DataSource方法的优点, 该方法成为获得连接的推荐方法. 所有基于JDBC 2.0的驱动器应该会包含DataSource接口的实现以及javax.sql包.

  对普通程序员而言, DataSource对象方法只是一种选择. 如果要使用连接缓冲池(Connection pooling)或者分布式交换, 则必须使用DataSource对象获得连接.原因在下文中阐述.

  ★ Connection Pooling

  连接缓冲池是这样工作的:当一个应用程序关闭一个连接时, 这个连接并不真正释放而是被循环利用.因为建立连接是消耗较大的操作, 循环利用连接可以显著的提高性能,因为可以减少新连接的建立.

  比如一个应用程序需要连接一个由名字是EmployeeDB的DataSource对象代表的数据源, 通过缓冲池获得连接的代码演示如下:

  Context ctx = new InitialContext();

  DataSource ds = (DataSource) ctx.lookup("jdbc/EmloyeeDB");

  Connection con = ds.getConnection("password","username");

  因为连接的数据源不同所以和上面的例子中的名字不一样. DataSource.getConnction方法返回的连接是否被缓存完全依赖于该DataSource对象的实现方式. 如果它将用于支持连接缓冲的中间层服务器(Middle Tier Server), 则DataSource对象将自动返回将被缓存、循环利用的连接.

  基本上不需要改变任何代码就可以获得缓冲池连接. 唯一需要注意的就是(我们已经这样做了:P),需要在finally块中释放连接,这应该是释放所有连接的较好方法.这样, 即使抛出了异常, 连接也会还给连接缓冲池:

  finally{

  if(con != null) con.close();

  }

  finally块保证了连接的循环利用.

  ★ Distributed Transactions(分布式交换)

  获得用于分布式交换的情形类似于获得缓冲池连接. 差别仍然是DataSource对象的实现方式, 而不是获得连接程序代码的不同.

  假定DataSource类被实现为用于中间件的分布式交换设施,下面的代码将获得用于分布式交换的连接:

  Context ctx = new InitialContext();

  DataSource ds = (DataSource) ctx.lookup("jdbc/EmloyeeDB");

  Connection con = ds.getConnection("password","username");

  出于性能的考虑, 用于获得分布式交换的连接的DataSource对象差不多总是会同时实现缓冲池连接.

  从程序员的角度来看, 获得普通连接和获得用于分布式交换的连接之间没有区别. 唯一的不同是交换界限(什么时候开始,什么时候结束)由交换管理器在后台处理. 应用程序不应该做任何妨碍交换管理器的事情. 所以程序不能直接调用commit或者rollback方法, 不能设置auto-commit模式.

  下面几行代码中con是可用于分布式交换的Connection对象, 演示了在con参与分布式交换是不能作的事情:

  con.commit();

  or

  con.rollback();

  or

  con.setAutoCommit(true);

  普通连接默认打开auto-commit模式. 用于分布式交换的连接对象默认关闭auto-commit模式. 应注意的是用于分布式交换的连接也可以用于非分布式交换模式, 交换边界的限制仅在连接是分布式交换一部分是有效.

  实现支持连接缓冲池的DataSource对象,需要实现ConnectionPoolDataSource对象, 三层构架的中间件的连接缓冲模块将会使用它. 同样, 实现支持分布式交换的DataSource对象也需要实现XADataSource对象, 中间件的分布式交换构件会使用该对象.

  ConnectionPoolDataSource和XADataSource对象对程序员而言是完全透明的, 应有驱动程序厂商提供.

  ★ Rowsets

  RowSet对象是一系列rows的容器. 根据不通的目的,可以通过多种方式实现. RowSet接口和其相关接口与JDBC 2.0标准扩展的其他部分的差别是它们不是驱动程序实现的一部分. RowSet对象在驱动程序的上层实现,可以被任何人实现.

  任何rowset类型都要实现RowSet接口(继承了ResultSet接口). 所以RowSet对象拥有ResultSet对象的所有功能:可以用getXXX方法取值,用updateXXX方法更新, 移动游标, 执行其他相关任务.

  当然rowset也有其新功能.作为JavaBeans组件, RowSet对象提供了方法监听属性的get/set.其中一个属性是command串,这个属性往往是一个查询,RowSet接口提供可设置command属性和执行之的方法. 这意味这RowSet对象能够执行自己的检索命令用查询结果填充自己的内容. 或者RowSet对象可以实现用来使用任何表格式的数据源填充自己, 而不是局限于关系数据库.

  从数据源取得数据后, RowSet对象可以断开于数据源的连接,这使得该对象很小(如果数据量特别不大). rowset也可以序列化. 所以rowset很小并可以序列化, 一个断开连接的rowset是传送数据给瘦客户机的理想工具.

  rowset可以被更新,然后重新连接数据源以传送更新的值. 如果设置了监听者, 当rowset中的游标被移动和内容变化时,会通知监听者.

  如, 图形界面组件(如条图)可以被注册为监听者,当rowset上有事件发生将会同志它, 它可以重画自身反映变化.

资源下载