当前位置: 首页 > 面试题库 >

JDBC类型滚动不敏感和敏感

闾丘德业
2023-03-14
问题内容

在理解Java JDBC ResultSet
Types时,有两种滚动类型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

那里有类似的问题,但是没有一个真正说明问题,所以我不将这个问题标记为重复:

ResultSet.TYPE_SCROLL_SENSITIVE的行为

JDBC结果集Type_Scroll_Sensitive

JDBC结果集类型滚动敏感

简短的回答 是, 默认获取你所使用的大小来高去观察一个单列的更新

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



 类似资料:
  • 问题内容: 在Microsoft SQL Server中,可以指定“不区分重音”的排序规则(对于数据库,表或列),这意味着可以对诸如 查找具有名称的行。 我知道可以使用unaccent_string contrib函数从PostgreSQL中的字符串中去除重音符号,但是我想知道PostgreSQL是否支持这些“不区分重音符号”的排序规则,因此上述方法可行。 问题答案: 为此,请使用 unaccen

  • 一、本功能说明 对网站内容进行过滤屏蔽,以免违反互联网相关政策而导致网站被关闭 二、子功能导航 1.添加敏感词 2.修改敏感词 2.删除敏感词 三、功能详解 1.添加敏感词 1).如何进入本功能 导航栏 选择扩展 -> 菜单栏 选择 敏感词管理-> 顶部添加敏感词或者批量导入 2).界面解释 a.)点击添加敏感词后显示如下界面 界面详述 1). 敏感词: 请填写您要屏蔽的任何词语 2). 替换词:

  • 磁敏传感器可以检测模块周围是否有磁体。 生活实例 扫地机器人的虚拟墙使用了磁场检测来判断能否通行。 参数 尺寸:24×20mm 检测距离:<1cm 工作电流:15mA

  • 磁敏传感器可以检测模块周围是否有磁体。 生活实例 扫地机器人的虚拟墙使用了磁场检测来判断能否通行。 参数 尺寸:24×20mm 检测距离:<1cm 工作电流:15mA

  • 随着在线应用程序日复一日地涌入互联网,并非所有应用程序都受到保护。许多Web应用程序无法正确保护敏感用户数据,如信用卡信息/银行帐户信息/身份验证凭据。黑客可能最终窃取这些受到弱保护的数据,以进行信用卡欺诈,身份盗窃或其他犯罪。 下面我们来了解这个漏洞的威胁代理,攻击向量,安全弱点,技术影响和业务影响。 威胁代理 - 谁可以访问您的敏感数据和任何数据备份。有外部和内部威胁。 攻击者的方法 - 做中

  • 如果在不同的目录中写入两个具有相同不区分大小写名称的公共Java类,那么这两个类在运行时都不可用。(我在Windows、Mac和Linux上测试了HotSpot JVM的几个版本。如果有其他JVM可以同时使用,我不会感到惊讶。(例如,如果我创建一个名为的类和一个名为的类,如下所示: 我的网站上提供了三个包含上述代码的eclipse项目。 如果尝试我调用在两个类上像这样: typechecker成功