Insecure Direct Object References定义与JDBC ResultSet API非常相似。
数据库光标只能像database cursor一样向前。
数据库光标可以滚动,甚至可以像ResultSet.TYPE_FORWARD_ONLY那样设置灵敏度设置。
甚至对位置更新/删除的支持也被复制到JDBC ResultSet.HOLD_CURSORS_OVER_COMMIT
但尽管有这些相似之处,ResultSet.CONCUR_UPDATABLE:
MySQL不支持SQL游标,而JDBC驱动程序则不支持 模仿它们,因此setCursorName()无效。
那么,JDBC实现是否是模仿数据库游标实现的数据访问规范,即使数据库不支持这样的功能呢?
答案 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。