IBM DB2 Driver for JDBC and SQLJ 有一个称为 useRowsetCursor 的数据源属性。该属性的默认值是 true,这意味着在服务器支持的情况下,驱动程序将尝试对可滚动游标使用多行获取(MRF)。该属性允许应用程序在必要时将 MRF 设置为 off。还没有针对单进游标的 MRF 支持。另外,T2zos (DB2 V9 for z/OS) 尚未支持 MRF。
目前,MRF 支持有 3 个公共接口:
- public void setUseRowsetCursor (boolean useRowsetCursor);
- public boolean getUseRowsetCursor ();
- public boolean getUseRowsetCursor (java.util.Properties properties);
不过,这不能当成 T2zos 的常规解决方案。这是因为 T2zos 需要行集支持来获得默认的 false 或 unset。该需求导致需要使用新的属性覆盖当前的 useRowsetCursor 属性(将在下面的 新连接属性 小节进一步阐述该属性)。另外,对于 T2zos,新的属性可用于单进游标和可滚动游标。在 IBM DB2 Driver for JDBC and SQLJ 版本 3.7.xx、3.51.xx、4.1.xx 和更新版本中,都启用了 MRF for T2zos (DB2 V9 for z/OS) 额外支持。
多行获取允许您从结果表中获取 0 行或多行。与获取一个行不同,您可以获取一组行(称为行集)。
如 图 1 所示,通过获取多个行,应用程序减少了 SQL 调用,并且可以使用一个 FETCH 语句获取行集。这不仅减少 SQL Application Programming Interface (API) 的交叉使用,还减少了应用程序的该函数的 CPU 使用。
图 1. 单行获取和多行获取比较
与 MRF 相关的新连接属性是 enableRowsetSupport。该属性的可用值包括:
- NOT_SET(默认值)
- YES
- NO
当 enableRowsetSupport 连接属性设置为 YES 或 NO 时,它将使用 useRowsetCursor 覆盖当前的设置。
对于 T2zos,如果 enableRowsetSupport 的值为 NOT_SET,这意味着没有 MRF 支持。对于 T4 和 T2u,NOT_SET 导致使用 useRowsetCursor 属性的当前值,该属性的默认值为 true。这意味着如果服务器在 T4 和 T2u 上支持它,将仅对可滚动游标使用 MRF。T4 和 T2u 用户可以将 useRowsetCursor 设置为 false 或将 enableRowsetSupport 设置为 NO 关闭该行为。
要启用 MRF,将 enableRowsetSupport 设置为 YES。如果服务器支持,T2zos 将对可滚动游标和单进游标使用 MRF。在未来,T4 和 T2u 可能选择仅对单进游标使用 MRF。
要禁用 MRF,将 enableRowsetSupport 设置为 NO。这意味着 MRF 对所有类型的用户禁用(T2zos、T4 和 T2u)。
下面是用于覆盖 useRowsetCursor 属性的当前设置的新属性:
- public void setEnableRowsetSupport(int enableRowsetSupport);
- public int getEnableRowsetSupport();
- public int getEnableRowsetSupport(java.util.Properties properties);
IBM Data Server Driver for JDBC and SQLJ 支持执行遵循 JDBC 1 标准的定位 UPDATE 或 DELETE 操作。对于行集游标,JDBC 1 定位更新语法必须知道行集的存在。该语法必须遵循以下格式:
update table set.... where current of cursor for row N of rowset
如果应用程序想要使用 JDBC 1 定位 UPDATE 操作,那么它必须构建正确定位的 UPDATE/DELETE 语句。
不过,当前的 t2zos 应用程序仍然使用 JDBC 1 定位 UPDATE 语句,其遵循的格式如下:
update table set....where current of cursor
因此,行集支持导致不同的行为。UPDATE 影响整个行集,而不是单个行。因此,t2zos 行集支持的默认设置为 false(见 新连接属性 小节)。
该技术涉及到使用 ResultSet.getCursorName 方法为 ResultSet 获取游标的名称,以及按照以下格式定义定位 UPDATE 或定位 DELETE 语句:
UPDATE table SET col1=value1…coln=valueN WHERE CURRENT OF cursorname
DELETE FROM table WHERE CURRENT OF cursorname
如果您使用 JDBC 1 技术对支持多行获取的数据源中的数据执行 UPDATE 或 DELETE 操作,定位 UPDATE 或 DELETE 语句可能 UPDATE 或 DELETE 多个行,尽管您可能希望它仅 UPDATE 或 DELETE 单个行。
要避免意外的 UPDATE 或 DELETE 操作,您可以采取以下措施之一:
- 使用可更新的 ResultSet 一次仅获取和 UPDATE 一个行。
- 在 UPDATE 或 DELETE 语句中使用 FOR ROW n OF ROWSET 子句, 以识别需要执行 MODIFY 或 DELETE 操作的特定行。
清单 1 使用一个样例 Java 程序,它演示如何使用新的 enableRowsetSupport 连接属性覆盖当前的 useRowsetCursor 属性。
该程序将 enableRowsetSupport 设置为 YES,这意味着将启用 MRF。
清单 1. 样例程序:connectionInfo_MRF.java
import java.sql.*; public class connectionInfo_MRF { public static void main(String[] args) throws Exception { System.out.println("\nTest case begins !!!\n "); javax.sql.DataSource ds = new com.ibm.db2.jcc.DB2SimpleDataSource(); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setServerName("ServerName"); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setPortNumber(portNumber); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDatabaseName("databaseName"); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDriverType(2); // Enable MRF support. To disable MRF, set setEnableRowsetSupport // to com.ibm.db2.jcc.DB2BaseDataSource.YES int setValue = com.ibm.db2.jcc.DB2BaseDataSource.YES; ((com.ibm.db2.jcc.DB2BaseDataSource)ds).setEnableRowsetSupport(setValue); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setTraceFile("jccTrace.txt"); System.out.println(((com.ibm.db2.jcc.DB2BaseDataSource) ds).getJccVersion()); java.sql.Connection con = ds.getConnection("userName", "passWord"); // Get Rowset support value. When MRF is enabled this should return value 1. int RowSet = ((com.ibm.db2.jcc.DB2BaseDataSource)ds).getEnableRowsetSupport(); System.out.println("\nRow Set Support value :" +RowSet); System.out.println("\n"); // Set the cursor type to scrollable. //Modify the below statement if you want the cursor type to be TYPE_FORWARD_ONLY java.sql.Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); // Create table s.executeUpdate ("create table TestQBatch (col1 int)"); // Populate tables with data. for (int i =1; i less than 1000; i++) { s.executeUpdate ("insert into TestQBatch values (" +i+ ")"); } java.sql.ResultSet rs = s.executeQuery("Select * from TestQBatch"); while (rs.next()) { System.out.print (rs.getInt (1) + " "); } // When MRF is enabled, ResultSet.getFetchSize() should alway return value > 1. int ActualResult = rs.getFetchSize(); System.out.print ("\n\nFetch Size : " +ActualResult); // Drop the table created. s.executeUpdate("DROP TABLE TestQBatch"); System.out.println("\n\nTest case Ends !!! "); con.commit(); } }
- 由于受到 DB2 的限制,行集游标(MRF)与 T2zos (Fetch Continue) 中的渐进式流不兼容。
- 在 T2zos 中,如果您将 enableRowsetSupport 设置为 YES,并且服务器支持 MRF,那么 T2zos 将为游标准备 WITH ROWSET POSITIONING。不过,如果在游标中出现大对象或 XML,并且渐进式流使用默认值或设置为 on,将对 FETCH 语句关闭 MRF(OFF )。将重新准备 FETCH 语句,并且不包含行集定位。
- T2zos 不知道从存储过程返回的游标是不是一个行集,因此 t2zos 驱动程序仅允许对存储过程执行单行获取。
- T2zos 不支持从存储过程返回的并且是渐进式流形式的大对象或 XML。在获取继续 (T2zosCursor.getMoreData_) 调用期间,该情况可能导致抛出 -225 sqlcode。
- 如果游标中出现大对象或 XML,T2zos java 存储过程将关闭行集支持。
使用多行获取 (MRF),您可以获得比使用 FETCH 语句每次获取一行更佳的性能。本文帮助您理解了 MRF 及其使用方式。此外,还通过一个简单的样例 Java 程序演示如何在 Java 程序中设置 MRF,并解释如何确定是否使用了 MRF。
-
转自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0909rowsetdb2zos/index.html
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15082138/viewspace-621615/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15082138/viewspace-621615/