JDBC类型滚动不敏感和敏感

在理解Java JDBC

ResultSet类型时,有两种滚动类型TYPE_SCROLL_SENSITIVE和TYPE_SCROLL_INSENSITIVE,我知道。但是当我进行实际实施时,我没有看到效果。下面是代码:

package com.jdbc.resultsettypeandconcurrency;

import java.sql.Connection;

import java.sql.DatabaseMetaData;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class TypeInSensitiveConcurUpdate {

public static void main(String[] args) {

Connection con = null;

Statement stmt = null;

try {

System.out.println("loading the driver.....");

Class.forName("oracle.jdbc.driver.OracleDriver");

System.out.println("Driver loaded");

con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "user", "pass");

if(con!=null) {

System.out.println("Connected to database");

} else {

System.out.println("Could not Get Connection");

}

stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

ResultSet rs = stmt.executeQuery(query);

System.out.println();

int cnt = 1;

while(rs.next()) {

System.out.print(rs.getString("COF_NAME")+", ");

System.out.print(rs.getInt("SUP_ID")+", ");

System.out.print(rs.getFloat("PRICE")+", ");

System.out.print(rs.getInt("SALES")+", ");

System.out.print(rs.getInt("TOTAL")+"\n");

if(cnt == 2){

try {

Thread.sleep(20 * 1000);/**LINE:39*/

} catch (InterruptedException e) {

e.printStackTrace();

}

}

cnt++;

}

System.out.println();

} catch(ClassNotFoundException e) {

System.out.println("ClassNotFoundException : Driver Class not found");

System.out.println(e.getMessage());

} catch(SQLException e) {

System.out.println("SQL Error "+e.getMessage());

System.out.println(e.getErrorCode());

} finally {

if(stmt!=null) {

stmt.close();

}

if(con!=null) {

con.close();

}

System.out.println("All Connection closed");

}

}

}

当程序到达LINE

39时,我从后端更新了数据库以进行记录。对于TYPE_SCROLL_INSENSITIVE,它不显示应执行的更新记录,但对于TYPE_SCROLL_SENSITIVE,则未执行所需的行为。它必须显示更新的记录,但不显示。谁能说出为什么呢?

我在googled处(不是Java doc或JLS)读到某个地方的ODBC瘦驱动程序,OCI驱动程序支持INSENSITIVE

ResultSet对象并且不敏感。是这样吗?如果是,为什么以及哪个驱动程序同时支持两者?如果否,那么我要去哪里错了。

编辑:添加了这些行以检查支持

DatabaseMetaData meta = con.getMetaData();

System.out.println("{TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE} -> "+

meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE));

System.out.println("{TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE} -> "+

meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE));

System.out.println("{TYPE_SCROLL_SENSITIVE, CONCUR_READ_ONLY} -> "+

meta.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY));

以下是我得到的结果:

{TYPE_SCROLL_INSENSITIVE,CONCUR_UPDATABLE}-> true

{TYPE_SCROLL_SENSITIVE,CONCUR_UPDATABLE}-> true

{TYPE_SCROLL_SENSITIVE,CONCUR_READ_ONLY}-> true

回答:

与其他 不起作用的

功能一样,使用它们之前必须阅读文档。

重要的是窗口的概念

滚动敏感结果集的Oracle实现涉及窗口的概念,窗口的大小基于访存大小。窗口大小影响结果集中更新行的频率。

因此,要观察每一行的变化,必须将 提取大小 设置为1。

请注意,不足以设置 resultSet 的获取大小,因为默认的获取大小为10,并且更改仅对第11行及后续行有效。

因此,必须在以下位置设置抓取大小prepareStatement

 def stmt = con.prepareStatement("""select id, val from test

where id between ? and ? order by id""", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)

stmt.setFetchSize(1)

// set bind variables and execute statement

现在,每次调用rs.next()都会打开一个新窗口,这会导致内部调用refreshRow

从数据库获取当前值。

请注意,此行为仅执行一次TYPE_SCROLL_SENSITIVETYPE_SCROLL_INSENSITIVE否则将

refreshRow被调用,因此即使您切换窗口,也可以看到初始查询时的常量数据。您可以refreshRow显式调用以看到相同的效果。

从技术上讲,该功能是使用两个游标实现的。第一个与使用的查询相对应,仅添加ROWID列。

 select rowid as "__Oracle_JDBC_internal_ROWID__", id, val from test

where id between :1 and :2 order by id

在每个窗口开关上调用的第二个游标(即,对于所获取的每一行,其获取大小= 1)简单外部将rowid第一个游标的保存与查询联接起来以重新获取当前数据。

WITH "__JDBC_ROWIDS__" AS (SELECT COLUMN_VALUE ID, ROWNUM NUM FROM TABLE(:1 ))

SELECT "__JDBC_ORIGINAL__".*

FROM (select rowid as "__Oracle_JDBC_internal_ROWID__", id, val from test

where id between :2 and :3 order by id) "__JDBC_ORIGINAL__", "__JDBC_ROWIDS__"

WHERE "__JDBC_ORIGINAL__"."__Oracle_JDBC_internal_ROWID__"(+) = "__JDBC_ROWIDS__".ID

ORDER BY "__JDBC_ROWIDS__".NUM

简短的回答 是, 。

测试完成于 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0

DriverVersion 12.2.0.1.0

以上是 JDBC类型滚动不敏感和敏感 的全部内容, 来源链接: utcz.com/qa/397758.html

回到顶部