zoukankan      html  css  js  c++  java
  • JDBC 查询的三大参数

    本文转载至 http://blog.csdn.net/turkeyzhou/article/details/5115228

    DBC1.0 、JDBC2.0 、JDBC3.0 中分别用以下方法创建Statement 。

    JDBC1.0 : createStatement()

    JDBC2.0 : createStatement(resultSetType, resultSetConcurrency)

    JDBC3.0 : createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)

    下面依次分析resultSetType 、resultSetConcurrency 、resultSetHoldability 这几个参数的含义。

    一 ResultSetType

          resultSetType 的可选值有: ResultSet.TYPE_FORWARD_ONLY 、ResultSet.TYPE_SCROLL_INSENSITIVE、ResultSet.TYPE_SCROLL_SENSITIVE 。

     

    :ResultSet.TYPE_FORWARD_ONLY

    默认的cursor 类型,仅仅支持结果集forward ,不支持backforward ,random ,last ,first 等操作。  

     

    :ResultSet.TYPE_SCROLL_INSENSITIVE

    支持结果集backforward ,random ,last ,first 等操作,对其它session 对数据库中数据做出的更改是不敏感的。

    实现方法:从数据库取出数据后,会把全部数据缓存到cache 中,对结果集的后续操作,是操作的cache 中的数据,数据库中记录发生变化后,不影响cache 中的数据,所以ResultSet 对结果集中的数据是INSENSITIVE 的。

     

    :ResultSet.TYPE_SCROLL_SENSITIVE

    支持结果集backforward ,random ,last ,first 等操作,对其它session 对数据库中数据做出的更改是敏感的,即其他session 修改了数据库中的数据,会反应到本结果集中。

     

    实现方法:从数据库取出数据后,不是把全部数据缓存到cache 中,而是把每条数据的rowid 缓存到cache 中,对结果集后续操作时,是根据rowid 再去数据库中取数据。所以数据库中记录发生变化后,通过ResultSet 取出的记录是最新的,即ResultSet是SENSITIVE 的。 但insert 和delete 操作不会影响到ResultSet ,因为insert 数据的rowid 不在ResultSet 取出的rowid 中,所以insert的数据对ResultSet 是不可见的,而delete 数据的rowid 依旧在ResultSet 中,所以ResultSet 仍可以取出被删除的记录( 因为一般数据库的删除是标记删除,不是真正在数据库文件中删除 )。

     

    做个试验,验证一下SENSITIVE 特性。数据库为oracle10g ,驱动为ojdbc14.jar 。

    test 表中数据如下:

    c1 c2 c3
    1c1 1c2 1c3
    2c1 2c2 2c3
    3c1 3c2 3c3

    程序如下:

    1. public static void testResultSetSensitive(Connection conn) throws Exception{   
    2.   
    3.         String sql = "SELECT c1,c2,c3 FROM test";   
    4.         try {   
    5.             Statement stmt = conn   
    6.                     .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);   
    7.                
    8.             ResultSet rs = stmt.executeQuery(sql);   
    9.                
    10.             while (rs.next()) {   
    11.                 System.out.println("[行号:" + rs.getRow() + "]/t" + rs.getString(1) + "/t" + rs.getString(2)   
    12.                         + "/t" + rs.getString(3));   
    13.                 Thread.sleep(20000);   
    14.             }   
    15.                
    16.             rs.close();   
    17.             stmt.close();   
    18.         } catch (SQLException e) {   
    19.             e.printStackTrace();   
    20.         } finally {   
    21.             try {   
    22.                 conn.close();   
    23.             } catch (Exception e) {   
    24.             }   
    25.         }   
    26.     }  
    1. public static void testResultSetSensitive(Connection conn) throws Exception{  
    2.   
    3.         String sql = "SELECT c1,c2,c3 FROM test";  
    4.         try {  
    5.             Statement stmt = conn  
    6.                     .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);  
    7.               
    8.             ResultSet rs = stmt.executeQuery(sql);  
    9.               
    10.             while (rs.next()) {  
    11.                 System.out.println("[行号:" + rs.getRow() + "]/t" + rs.getString(1) + "/t" + rs.getString(2)  
    12.                         + "/t" + rs.getString(3));  
    13.                 Thread.sleep(20000);  
    14.             }  
    15.               
    16.             rs.close();  
    17.             stmt.close();  
    18.         } catch (SQLException e) {  
    19.             e.printStackTrace();  
    20.         } finally {  
    21.             try {  
    22.                 conn.close();  
    23.             } catch (Exception e) {  
    24.             }  
    25.         }  
    26.     }  

    定义ResultSet 为 ResultSet. TYPE_SCROLL_SENSITIVE 类型,首先执行 sql 访问数据库,然后执行 rs.next() 移动游标取数据。在循环里面加上 Thread.sleep (20000) 的目的是为了我们有时间在后台把数据库里的数据改了。比如当在循环里打印出第一行的数据后,我们在后台,把第三行数据的 c3 列改成 ”3uuu” 。如果 ResultSet 真的是敏感的话,那应该取出 ”3uuu” ,而不是原始的“ 3c3 ”。但最终的结果却是如下:

     

    [ 行号: 1] 1c1   1c2   1c3

    [ 行号: 2] 2c1   2c2   2c3

    [ 行号: 3] 3c1   3c2   3c3

    数据没变呀,ResultSet 不敏感啊!于是去查阅资料,找了n 久,还是在英文文档上找到了答案。原来是fetchsize 的问题。调用ResultSet 的next 方法取数据时,并不是每调用一次方法就去数据库里查一次,而是有个fetchSize, 一次取fetchSize 条数据。Oracle默认的fetchsize 等于10 ,所以上面的代码在第一次调用rs.next() 时,就已经把3 条数据都取出来了,所以才会有上面的结果。

     

          第二次实验,在ResultSet rs = stmt.executeQuery(sql); 前面加上 stmt.setFetchSize(1); 将fetchSize 设置为1 。然后重新第一次实验的步骤,发现最 终结果为:

    [ 行号: 1] 1c1   1c2   1c3

    [ 行号: 2] 2c1   2c2   2c3

    [ 行号: 3] 3c1   3c2   3uuu

        原因就是 fetchsize 设置为 1 时,每次 next 取数时都会重新用 rowid 取数据库里取数据,当然取到的是最新的数据了。

      

          二 ResultSetConcurrency

          ResultSetConcurrency的可选值有2个:
          ResultSet.CONCUR_READ_ONLY 在ResultSet中的数据记录是只读的,不可以修改
          ResultSet.CONCUR_UPDATABLE 在ResultSet中的数据记录可以任意修改,然后更新到数据库,可以插入,删除,修改。

          三 ResultSetHoldability

       ResultSetHoldability 的可选值有2 个 :

         HOLD_CURSORS_OVER_COMMIT: 在事务commit 或rollback 后,ResultSet 仍然可用。 
         CLOSE_CURSORS_AT_COMMIT: 在事务commit 或rollback 后,ResultSet 被关闭。

      

         需要注意的地方:

       1 :Oracle 只支持HOLD_CURSORS_OVER_COMMIT 。

       2 :当Statement 执行下一个查询,生成第二个ResultSet 时,第一个ResultSet 会被关闭,这和是否支持支持HOLD_CURSORS_OVER_COMMIT 无关。

         四 验证数据库是否支持ResultSet的各种特性

    不同的数据库版本及 JDBC 驱动版本,对 ResultSet 的各种高级特性的支持是不一样的,我们可以通过以下方法,来验证具体的数据库及 JDBC 驱动,是否支持 ResultSet 的各种特性。

        

         DatabaseMetaData dbMeta = conn.getMetaData();

          然后调用 DatabaseMetaData 对象的以下方法:

           boolean supportsResultSetType(int resultSetType);

           boolean supportsResultSetConcurrency(int type, int concurrency);

           boolean supportsResultSetHoldability(int holdability);

  • 相关阅读:
    NOIP普及组2003经验总结
    Day6上午 DP练习题
    Day4 图论
    Day3 数据结构
    使用ettercap进行dns欺骗和获取目标浏览的图片
    flask入门
    攻防世界-web-unserialize3
    数据结构课设作业-----飞机订票系统
    bugku NaNNaNNaNNaN-Batman
    it's a test
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/10244645.html
Copyright © 2011-2022 走看看