JDBC ResultSet是应用程序级查询游标

时间:2015-09-18 05:45:31

标签: java mysql database jdbc cursor

Insecure Direct Object References定义与JDBC ResultSet API非常相似。

但尽管有这些相似之处,ResultSet.CONCUR_UPDATABLE

  

MySQL不支持SQL游标,而JDBC驱动程序则不支持   模仿它们,因此setCursorName()无效。

那么,JDBC实现是否是模仿数据库游标实现的数据访问规范,即使数据库不支持这样的功能呢?

3 个答案:

答案 0 :(得分:5)

你当然可以这样想。所有这些概念都是从ODBC继承的,所以你可以感谢(责备?)历史记录。大多数dbs都没有广泛支持游标,因为在JDBC等API中提供了这些功能。特别是在MySQL中,有一个游标" fetch"从MySQL 5.0开始支持,这意味着驱动程序不会被迫读取整个结果,无论是否需要。这意味着可以在很少或没有成本的情况下尽早放弃结果集。但是,需要额外的往返来定期请求行块。 MySQL Connector / J默认情况下不强制执行FORWARD_ONLY语义,并将整个结果缓存在客户端中,允许"可滚动性"。但是,由于服务器中的实现,这不允许对在其他事务中提交的更改敏感。通常可以模拟/模拟功能,以提供API的便利性。

答案 1 :(得分:4)

名字里有什么......

实际上,ResultSet和数据库游标在语义上是相似的。 The SQL:2011 standard指定:

  

游标是一种机制,通过该机制,可以一次一个地对行的行进行操作(例如,返回到主编程语言)。

这听起来很像ResultSet。再往下,SQL:2011标准继续提及:

  

游标声明描述符和结果集描述符有四个属性:sensitivity属性(SENSITIVE,INSENSITIVE或ASENSITIVE),可滚动性属性(SCROLL或NO SCROLL),可保持性属性(WITH HOLD或WITHOUT HOLD) )和returnability属性(WITH RETURN或WITHOUT RETURN)。

换句话说,这些功能都不是由JDBC(或ODBC)规范团队“发明”的。它们在许多SQL数据库实现中确实以这种形式存在,并且与任何规范一样,上述许多功能在SQL实现中也是可选的。

你已经在Jess已经对MySQL部分做出了权威的回应。我想补充一点,JDBC与高级别的任何规范一样,具有必需的部分和可选的部分。

查看JDBC Spec,我可以看到以下相关部分。

  

6.3 JDBC 4.2 API合规性

     

符合JDBC规范的驱动程序必须执行以下操作:

     

[...]

     

它必须实现Statement接口,但以下情况除外   可选方法:

     
      
  • [...]
  •   
  • 调用setCursorName
  •   
  • [...]
  •   
     

它必须实现ResultSet接口,但以下情况除外   可选方法:

     
      
  • [...]
  •   
  • 调用getCursorName
  •   
  • [...]
  •   

ResultSet类型的实现也是如此。在规格中,你会发现:

  

方法DatabaseMetaData.supportsResultSetType如果是,则返回true   驱动程序支持指定的类型,否则为false

答案 2 :(得分:1)

基于我对JDBC ResultSet的理解,我会说它不依赖于它连接的数据库,它的行为是相同的。

JDBC将始终将默认行数(而不是整个结果集)提取到本地内存。一旦到达获取行的最后一行(比如通过执行next()并尝试访问下一行),如果结果中有更多行,则将对数据库进行另一次往返调用以获取下一行批量行到本地内存。

即使您可以设置要在本地内存中获取的行数,也可以考虑使用CachedRowSet。

当你在Statement上设置fetchSize()时,你只是给JDBC驱动程序一个指令,你应该提取多少,但JDBC驱动程序可以忽略你的指令。我不知道Oracle驱动程序对fetchSize()的作用。大多数情况下,它观察到MySQL JDBC驱动程序将始终获取所有行,除非您将fetchSize()设置为Integer.MIN_VALUE。