JDBC1.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 。
1 :ResultSet.TYPE_FORWARD_ONLY
默认的cursor 类型,仅仅支持结果集forward ,不支持backforward ,random ,last ,first 等操作。
2 :ResultSet.TYPE_SCROLL_INSENSITIVE
支持结果集backforward ,random ,last ,first 等操作,对其它session 对数据库中数据做出的更改是不敏感的。
实现方法:从数据库取出数据后,会把全部数据缓存到cache 中,对结果集的后续操作,是操作的cache 中的数据,数据库中记录发生变化后,不影响cache 中的数据,所以ResultSet 对结果集中的数据是INSENSITIVE 的。
3 :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 |
程序如下:
- public static void testResultSetSensitive(Connection conn) throws Exception{
- String sql = "SELECT c1,c2,c3 FROM test";
- try {
- Statement stmt = conn
- .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
- ResultSet rs = stmt.executeQuery(sql);
- while (rs.next()) {
- System.out.println("[行号:" + rs.getRow() + "]/t" + rs.getString(1) + "/t" + rs.getString(2)
- + "/t" + rs.getString(3));
- Thread.sleep(20000);
- }
- rs.close();
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (Exception e) {
- }
- }
- }
- public static void testResultSetSensitive(Connection conn) throws Exception{
- String sql = "SELECT c1,c2,c3 FROM test";
- try {
- Statement stmt = conn
- .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
- ResultSet rs = stmt.executeQuery(sql);
- while (rs.next()) {
- System.out.println("[行号:" + rs.getRow() + "]/t" + rs.getString(1) + "/t" + rs.getString(2)
- + "/t" + rs.getString(3));
- Thread.sleep(20000);
- }
- rs.close();
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (Exception e) {
- }
- }
- }
定义ResultSet 为 ResultSet. TYPE_SCROLL_SENSITIVE 类型,首先执行 sql 访问数据库,然后执行 rs.next() 移动游标取数据。在循环里面加上 Thread.sleep (20000) 的目的是为了我们有时间在后台把数据库里的数据改了。比如当在循环里打印出第一行的数据后,我们在后台,把第三行数据的 c3 列改成 ”3uuu” 。如果 ResultSet 真的是敏感的话,那应该取出 ”3uuu” ,而不是原始的“ 3c 3 ”。但最终的结果却是如下:
[ 行号: 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);
相关推荐
### JDBC连接数据库各种数据库参数详解 #### 一、Oracle8/8i/9i数据库(thin模式) 在Java中通过JDBC访问Oracle数据库时,通常采用thin驱动方式。thin驱动是一种纯Java驱动,无需依赖任何非Java代码即可完成与...
### MySQL JDBC配置参数详解 在Java应用程序中使用MySQL数据库时,通常会借助JDBC(Java Database Connectivity)技术来实现数据库连接与数据交互。为了优化性能、确保连接的有效性以及合理管理资源,正确设置JDBC...
"spring封装jdbc查询"是Spring框架中的一个核心功能,旨在简化传统的JDBC(Java Database Connectivity)操作,提高代码的可读性和可维护性,同时减少数据库操作中的潜在错误。以下是对这个主题的详细阐述: 首先,...
Weblogic JDBC 数据源配置和详细参数说明 一、JDBC 概述 JDBC(Java Database Connectivity)是 Java 语言中的一种标准数据库连接技术,几乎所有需要访问数据库的 J2EE 应用程序都直接或间接地使用了它。JDBC 提供...
这篇博文将详细解释MySQL JDBC URL的各个参数及其用途。 首先,JDBC URL的基本格式如下: ```text jdbc:mysql://[hostname]:[port]/[database]?[parameters] ``` - `jdbc:mysql://` 是固定的协议前缀,表示使用...
在文档提供的内容中,主要讨论了在Windchill环境下如何使用JDBC进行数据库查询,并且强调了在使用JDBC时应该注意wtconnection(Windchill的数据库连接对象)不应在Java代码中关闭。在下面的知识点中,我们将详细分析...
### JDBC参数配置详解 在Java开发中,JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。它由一组用Java语言编写的类和接口组成,通过JDBC驱动程序连接到...
本文将深入探讨这两个主题,特别是如何结合`StringBuffer`来实现JDBC的模糊查询。 首先,让我们了解`StringBuffer`。`StringBuffer`是Java中的一个类,它提供了字符串操作的功能,特别是在多线程环境中。与`String`...
本篇将深入讲解如何在使用JDBC时,通过统一的方式设置SQL语句中的参数,提高代码的可读性、可维护性和安全性。我们将探讨以下知识点: 1. JDBC基础: JDBC是Java平台中用于与关系数据库交互的一组接口和类。它提供...
Java使用Jdbc连接Oracle执行简单查询操作示例 Java使用Jdbc连接Oracle执行简单查询操作,是指使用Java语言通过Jdbc(Java Database Connectivity)连接Oracle数据库并执行简单查询操作的过程。本文将通过实例形式...
Apache Tomcat 的 JDBC-Pool 是一个内置的连接池实现,用于高效管理数据库连接。它提供了丰富的配置选项,以满足各种性能和稳定性需求。下面是对标题和描述中涉及的一些关键参数的详细解释: 1. **factory**:这个...
接着,我们准备了一个带有占位符的SQL查询,并设置了参数值。执行查询后,我们遍历`ResultSet`,打印出每一行的指定列名。 此外,为了优化性能和代码可读性,建议使用try-with-resources语句来自动关闭资源。这将在...
文章中提到了JDBC参数的三种类型: - **输入参数(IN)**:接收输入数据,常见于SQL语句和存储过程。在SQL语句执行前,IN参数必须赋值。在存储过程中,它们用于传递输入数据。 - **输出参数(OUT)**:在存储过程...
在`PreparedStatement`中,可以设置参数来实现模糊查询。 ```java String searchKeyword = "part"; pstmt = conn.prepareStatement("SELECT * FROM mytable WHERE column LIKE ?"); pstmt.setString(1, "%" + ...
- **分批处理**:可以考虑将大查询分成多个小查询来执行,每个查询只处理一部分数据。 - **关闭资源**:确保在使用完PreparedStatement和ResultSet之后及时关闭它们,释放资源。 - **使用流式处理**:如果可能的话,...
- `queryByPage(Connection conn, String sql, int pageNum, int pageSize)`:接收数据库连接、基础SQL语句以及分页参数,返回分页查询的结果。 - `getTotalRows(Connection conn, String countSql)`:用于计算总...
【标题】"jdbc+serlvet分页查询代码"涉及的知识点主要集中在Java数据库连接(JDBC)和Servlet两个核心技术上,它们是Web应用程序中处理数据和交互的关键组件。 **JDBC(Java Database Connectivity)** JDBC是Java...
标题中的“jdbc 查询小界面”指的是一个基于Java Swing开发的简单图形用户界面(GUI),用于执行SQL查询。这个应用程序利用了Java的Java Database Connectivity (JDBC) API来连接和操作数据库。JDBC是Java标准版...
本示例"JDBC查询代码以Student实体类.zip"提供了一个简单的JDBC查询应用,涉及到的关键知识点包括: 1. **JDBC驱动注册**:在Java程序中,我们需要通过`Class.forName()`方法加载并注册JDBC驱动。例如,对于MySQL,...
在JDBC 中对数据库的查询有一般查询、参数查询和存储过程这样三类。本例在此实现这三种查询方法。程序运行后先对数据库执行一般查询,接着执行参数查询,最后执行存储过程。程序运行结果将根据用户的数据库中数据来...