首页 » PHP教程 » phpresultset技巧_JDBC规范五ResultSet详解

phpresultset技巧_JDBC规范五ResultSet详解

duote123 2024-11-17 0

扫一扫用手机浏览

文章目录 [+]

(1)游标可操作的办法。
(2)ResultSet工具的修正对数据库的影响。

后者称为ResultSet工具的敏感性。
ResultSet有3种不同的类型,分别解释如下。

phpresultset技巧_JDBC规范五ResultSet详解

(1)TYPE_FORWARD_ONLY

phpresultset技巧_JDBC规范五ResultSet详解
(图片来自网络侵删)

这种类型的ResultSet不可滚动,游标只能向前移动,从第一行到末了一行,不许可向后移动,即只能利用ResultSet接口的next()方法,而不能利用previous()方法,否则会产生缺点。

(2)TYPE_SCROLL_INSENSITIVE这种类型的ResultSet是可滚动的,它的游标可以相对付当前位置向前或向后移动,也可以移动到绝对位置。
当ResultSet没有关闭时,ResultSet的修正对数据库不敏感,也便是说对ResultSet工具的修正不会影响对应的数据库中的记录。

(3)TYPE_SCROLL_SENSITIVE这种类型的ResultSet是可滚动的,它的游标可以相对付当前位置向前或向后移动,也可以移动到绝对位置。
当ResultSet没有关闭时,对ResultSet工具的修正会直接影响数据库中的记录。

默认情形下,ResultSet的类型为TYPE_FORWARD_ONLY。
DatabaseMetaData接口中供应了一个supportsResultSetType()方法,用于判断数据库驱动是否支持某种类型的ResultSet工具,如果支持,则返回true,否则返回false。
如果JDBC驱动不支持某一类型的ResultSet工具,在调用Connection工具的createStatement()、prepareStatement()或prepareCall()方法指定创建该类型的ResultSet工具时,会在Connection工具中产生一个SQLWarning工具,当Statement工具实行时,产生的ResultSet工具可以通过ResultSet工具的getType()方法确定它的类型。

2.ResultSet并行性

ResultSet工具的并行性决定了它支持更新的级别,目前JDBC中支持两个级别,分别如下:

CONCUR_READ_ONLY:为ResultSet工具设置这种属性后,只能从ResulSet工具中读取数据,但是不能更新ResultSet工具中的数据。

CONCUR_UPDATABLE:该属性表明,既可以从ResulSet工具中读取数据,又能更新ResultSet中的数据。

ResultSet工具默认并行性为CONCUR_READ_ONLY。
DatabaseMetaData接口中供应了一个supportsResultSetConcurrency()方法,用于判断JDBC驱动是否支持某一级别的并行性,如果支持就返回true,否则返回false。

如果JDBC不支持某一级别的并行性,则调用createStatement()、prepareStatement()或prepareCall()方法指定该级别时会在Connection工具中产生一个SQLWarning工具。
在运用程序中,可以调用ResultSet工具的getConcurrency()方法获取ResultSet的并行性级别。

3.ResultSet可保持性

调用Connection工具的commit()方法能够关闭当前事务中创建的ResultSet工具。
然而,在某些情形下,这可能不是我们期望的行为。
ResultSet工具的holdability属性使得运用程序能够在Connection工具的commit()方法调用后掌握ResultSet工具是否关闭。

下面两个常量用于在调用Connection工具的createStatement()、prepareStatement()或prepareCall()方法时指定ResultSet工具的可保持性。

HOLD_CURSORS_OVER_COMMIT:当调用Connection工具的commit()方法时,不关闭当前事务创建的ResultSet工具。

CLOSE_CURSORS_AT_COMMIT:当前事务创建的ResultSet工具在事务提交后会被关闭,对一些运用程序来说,这样能够提升系统性能。

ResultSet工具的默认可保持性取决于详细的驱动实现,DatabaseMetaData接口中供应了getResultSetHoldability()方法用于获取JDBC驱动的默认可保持性。
如果JDBC驱动不支持某一级别的可保持性,则调用createStatement()、prepareStatement()或prepareCall()方法指定该级别时,会在Connection工具中产生一个SQLWarning工具,运用程序可以调用ResultSet工具的getHoldability()方法获取ResultSet的可保持性。

4.ResultSet属性设置

ResultSet的类型、并行性和可保持性等属性可以在调用Connection工具的createStatement()、prepareStatement()或prepareCall()方法创建Statement工具时设置,例如:

Connection conn = ds.getConnection(user, passwd);Statement stmt = conn.createStatement(ResultSet.TYPE SCROLL INSENSITIVE,ResultSet.CONCUR READ ONLY,ResultSet.CLOSE CURSORS AT COMMIT);

上面的代码中,创建Statement工具时,指定ResultSet工具可以滚动,ResultSet中的数据不可以修正,而且在调用Connection工具的commit()方法提交事务时当前事务创建的ResultSet工具自动关闭。
Statement、PreparedStatement和CallableStatement接口中为这些属性供应了Getter方法,用于获取ResultSet的类型、并行性及可保持性等属性。

5.ResultSet游标移动

ResultSet工具中掩护了一个游标,游标指向当前数据行。
当ResultSet工具第一次创建时,游标指向数据的第一行。
ResultSet接口中供应了一系列的方法,用于操作ResultSet工具中的游标,这些方法的浸染如下。

next():游标向前移动一行,如果游标定位到下一行,则返回true;如果游标位于末了一行之后,则返回false。
previous():游标向后移动一行,如果游标定位到上一行,则返回true;如果游标位于第一行之前,则返回false。
first():游标移动到第一行,如果游标定位到第一行,则返回true;如果ResultSet工具中一行数据都没有,则返回false。

last():移动游标到末了一行,如果游标定位到末了一行,则返回true;如果ResultSet不包含任何数据行,则返回false。

beforeFirst():移动游标到ResultSet工具的第一行之前,如果ResultSet工具不包含任何数据行,则该方法不生效。

afterLast():游标位置移动到ResultSet工具末了一行之后,如果ResultSet工具中不包含任何行,则该方法不生效。

relative(int rows):相对付当前位置移动游标,如果参数rows为0,则游标不会移动。
如果rows为正数,则游标向前移动指定的行数,如果rows大于当前位置到末了一行的偏移量,则游标移动到末了一行之后。
如果rows为负数,则游标向后移动,如果rows大于当前位置到第一行的偏移量,则游标移动到第一行之前的位置。
当游尺度肯定位到某一行时,该方法返回true,否则返回false。
如果参数rows值为1,则该方法的效果和next()方法相同;如果rows参数为-1,则该方法的效果和previous()方法相同。

absolute(int row):游标定位到ResultSet工具中的第row行。
如果row为正数,则游标移动到ResultSet工具的第row行。
须要把稳的是,这里行的序数从1开始。
如果参数row大于ResultSet工具中的最大行数,则游标移动到末了一行之后。
如果参数row为负数,游标从行尾开始移动。
例如,row值为-1时,游标移动到末了一行;为-2时,游标移动到倒数第二行;如果row的绝对值大于最大行,则游标移动到第一行之前。

当ResultSet工具的类型为TYPE_FORWARD_ONLY时,游标只能向前移动,调用其他方法操作游标向后移动时将会抛出SQLException非常。

6.修正ResultSet工具

并行性为CONCUR_UPDATABLE的ResultSet工具可以利用ResultSet接口中供应的方法对其进行更新,包括更新行、删除行,在JDBC驱动支持的情形下,还可以插入新的行。

接下来我们就来理解一下如何利用ResultSet接口中供应的方法修正ResultSet工具。

首先来看一下如何更新ResultSet记录中的某一行,更新ResultSet工具中的某一行是一个两阶段的过程。
首先须要为某一行的每个字段设置新的值,然后更新修正到详细的行。
第一阶段完成后,底层数据库数据不会更新,第二阶段会把ResultSet工具的修正同步到数据库。
ResultSet接口针对所有JDBC类型,供应了两个更新方法,个中一个方法须要指定更新列的序数,另一个方法须要指定列的名称(大小写不敏感)。
如果在并行性级别为ResultSet.CONCUR_READ_ONLY的ResultSet工具上调用更新方法,将会抛出SQLException非常。
ResultSet工具的updateRow()方法用于将所有列的修正运用到当前行,并打消先前更新方法所做变动的记录。

public void testJdbc() { // 初始化数据 DbUtils.initData(); try { // 加载驱动 Class.forName("org.hsqldb.jdbcDriver"); // 获取Connection工具 Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis", "sa", ""); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet resultSet = statement.executeQuery("select from user limit 2"); // 遍历ResultSet ResultSetMetaData metaData = resultSet.getMetaData(); int columCount = metaData.getColumnCount(); while (resultSet.next()) { for (int i = 1; i <= columCount; i++) { String columName = metaData.getColumnName(i); String columVal = resultSet.getString(columName); System.out.println(columName + ":" + columVal); } System.out.println("--------------------------------------"); } // hsqldb 不支持 // 换成mysql System.out.println(connection.getMetaData().supportsResultSetType(ResultSet.CONCUR_UPDATABLE)); resultSet.first(); resultSet.updateString("NICK_NAME", "xuxu"); resultSet.updateRow(); System.out.println(resultSet.isClosed()); // 遍历ResultSet ResultSet resultSet2 = statement.executeQuery("select from rr_banner_bannermodel limit 1"); ResultSetMetaData metaData2 = resultSet2.getMetaData(); while (resultSet2.next()) { for (int i = 1; i <= columCount; i++) { String columName = metaData2.getColumnName(i); String columVal = resultSet2.getString(columName); System.out.println(columName + ":" + columVal); } System.out.println("--------------------------------------"); } // 关闭连接 IOUtils.closeQuietly(statement); IOUtils.closeQuietly(connection); } catch (Exception e) { e.printStackTrace(); } }

上面用的是hsqldb 驱动,hsqldb 驱动不支持CONCUR_READ_ONLY ,可以更新到mysql的驱动,这里只作为一个实例看看。

如上面的代码所示,实行查询SQL天生ResultSet工具后,调用next()方法将游标定位到第一行,然后调用updateString()方法更新第一行的nick_name字段,接着调用ResultSet的updateRow()方法将ResultSet工具的修正运用到数据库

DatabaseMetaData接口中的ownUpdatesAreVisible(int type)方法用于判断指定类型的ResultSet工具的更新是否对当前事务可见,如果可见,就返回true,否则返回false。
DatabaseMetaData接口的othersUpdatesAreVisible(int type)方法用于判断指定类型的ResultSet工具的更新是否对其他事务可见,如果可见,就返回true,否则返回false。
ResultSet工具可以调用rowUpdated()方法来判断是否调用了updateRow()方法确认更新。
对付任何给定的ResultSet,运用程序不应该在调用updateXXX()方法之后以及在调用后续的updateRow()或cancelRowUpdates()方法之前修正通过updateXXX()方法设置的参数值,否则可能会产生不可预期的效果。

接下来理解如何删除ResultSet工具中的某一行。
ResultSet工具中的行可以调用deleteRow()方法进行删除,例如:

rs.absolute(4)rs.deleteRow

将ResultSet工具的游标定位到某一行后,调用deleteRow()方法会删除数据库中对应的行。
这种删除对付一个打开的ResultSet工具是可见的,它会反响到ResultSet工具的变革—ResultSet工具会移除对应的行,或者把对应的行设置为空或无效行。
若如此,则调用DatabaseMetaData工具的ownDeletesAreVisible(int type)方法将返回true。
如果调用deleteRow()方法删除行后ResultSet工具中仍旧包含该行,那么调用DatabaseMetaData工具的ownDeletesAreVisible(int type)方法将返回false,意味着数据删除对当前ResultSet工具不可见。

DatabaseMetaData工具的othersDeletesAreVisible(int type)方法用于判断数据行的删除对其他事务中的ResultSet工具是否可见,如果返回值为true,就表明当前ResultSet行的删除对其他事务中的ResultSet工具是可见的,否则返回false。
当前行被删除后,如果ResultSet工具能够检测到行被删除,那么ResultSet工具的rowDeleted()方法会返回true,否则返回false。

末了,我们来理解一下如何向ResultSet工具中插入行。
在JDBC驱动支持的情形下,可以调用ResultSet接供词给的方法向ResultSet工具中插入行。
如果JDBC驱动不支持向ResultSet工具中插入行,就会抛出SQLFeatureNotSupportedException非常。

ResultSet工具中插入行须要以下几步:

(1)移动游标到待插入的位置。

(2)调用ResultSet接供词给的updateXXX()方法为每一个字段设置值。

(3)插入行到当前ResultSet工具中。

代码如下:

ResultSet rs = stmt.executeQuery("select author, title, isbn"from booklist");rs.moveToInsertRow();//为每列设置值rs.updateString(1,"Huxley, Aldous");rs.updateString(2,"Doors of Perception and Heaven and Hell");rs.updateLong(3,60900075);插入行rs.insertRow();//移动游标到插入前的行rs.moveToCurrentRow();

须要把稳的是,插入行中的每一个字段不许可为null,必须利用得当的updateXXX()方法指定一个确定的值。
如果updateXXX()方法指定的值与数据库字段类型不匹配,那么调用insertRow()方法会抛出SQLException非常。
如果新插入的行对ResultSet工具可见,那么调用DatabaseMetaData工具的ownInsertsAreVisible(int type)方法是返回true,否则返回false。
如果新插入的行对其他事务中的ResultSet工具可见,则调用DatabaseMetaData工具的othersInsertsAreVisible(int type)方法返回true。
如果ResultSet工具能够识别新插入的行,那么调用DatabaseMetaData工具的insertsAreDetected(int type)方法将会返回true,意味着插入行对ResultSet工具可见。

对付一个给定的ResultSet工具,调用updateXXX()方法为每一个字段设置值后,在insertRow()方法调用前,运用程序不可以修正参数值,否则可能产生不可预见的结果。

7.关闭ResultSet工具

ResultSet工具不才面两种情形下会显式地关闭:

(1)调用ResultSet工具的close()方法。

(2)创建ResultSet工具的Statement或者Connection工具被显式地关闭。

不才面两种情形下ResultSet工具会被隐式地关闭:

(1)干系联的Statement工具重复实行时。

(2)可保持性为CLOSE_CURSORS_AT_COMMIT的ResultSet工具在当前事务提交后会被关闭。

把稳一些JDBC驱动实现,当ResultSet类型为TYPE_FORWARD_ONLY并且next()方法返回false时,也会隐式地关闭ResultSet工具。
一旦ResultSet工具被关闭,调用除isClosed()和close()之外的方法就会抛出SQLException非常,但是通过ResultSet创建的ResultSetMetaData实例仍旧可以访问。

ResultSet工具关闭后,不会关闭由ResultSet工具创建的Blob、Clob、NClob或SQLXML工具,除非调用这些工具的free()方法。

相关文章