JAVA基础知识之JDBC——ResultSet的滚动和更新(statement的额外参数)

时间:2022-03-07 01:35:48

ResultSet不仅可以内存中的一张二维表一样保存statement执行SQL的结果集,还能通过结果集修改DB的数据。ResultSetMetaData则可以用来获得ResultSet对象的相关信息。

ResultSet支持滚动和并发,但需要在创建statement时候,额外传入参数

可滚动结果集

ResultSet用来定位行的方法有,next(),  last(), absolute(), previous(), afterLast()等等。

支持absolute(), previous(), afterLast()等方法的结果集,称为可滚动结果集。在创建PreparedStatement时,可以通过传入ResultSetType参数来支持可滚动结果集,

ResultSetType支持三种取值,

  • ResultSet.TYPE_FORWARD_ONLY, 只能向前移动(JDK1.4以前的默认值)
  • ResultSet.TYPE_SCROLL_INSENSITIVE, 可滚动,但是底层数据的改变不会影响结果集
  • ResultSet.TYPE_SCROLL_SENSITIVE, 可滚动,底层数据的改变会影响结果集

支持并发结果集

在创建statement时,传入resultSetConcurrency(即并发类型)可以控制结果集的并发性,resultSetConcurrency有两种取值

  • ResultSet.CONCUR_READ_ONLY,只读的并发模式(默认)
  • ResultSet.CONCUR_UPDATABLE,可更新的并发模式

另外,可更新的结果集还需要满足两个条件,

  • 所有数据都来自一个表;
  • 选出的数据集必须包含主键列

要通过结果集更新数据库,只需要调用ResultSet对象的updateXxx(index, value)方法修改和updateRow()方法提交即可。

对于支持以上两种特性的结果集,在创建statement时可以这么创建,

1 PreparedStatement pstmt = conn.prepareStatement(sql
2                         , ResultSet.TYPE_SCROLL_INSENSITIVE
3                         , ResultSet.CONCUR_UPDATABLE);

 

下面演示ResultSet的滚动和更新

 1 package db;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.IOException;
 6 import java.sql.Connection;
 7 import java.sql.DriverManager;
 8 import java.sql.PreparedStatement;
 9 import java.sql.ResultSet;
10 import java.sql.SQLException;
11 import java.util.Properties;
12 
13 public class ResultSetTest {
14     private String driver;
15     private String url;
16     private String user;
17     private String pass;
18     public void initParam(String paramFile) throws FileNotFoundException, IOException, ClassNotFoundException {
19         //用Properties类加载属性文件
20         Properties prop = new Properties();
21         prop.load(new FileInputStream(paramFile));
22         driver = prop.getProperty("driver");
23         url = prop.getProperty("url");
24         user = prop.getProperty("user");
25         pass = prop.getProperty("pass");
26         Class.forName(driver);
27     }
28     
29     public void query(String sql) throws SQLException {
30         try (
31                 Connection conn = DriverManager.getConnection(url, user, pass);
32                 //创建prepareStatement可以传入额外参数,用来控制结果集是否支持滚动和更新
33                 //传入两个额外参数,即ResultSet中的两个常量
34                 //TYPE_SCROLL_INSENSITIVE表示结果集可滚动,但底层数据改变不会影响ResultSet的内容
35                 //CONCUR_UPDATABLE支持ResultSet可更新的并发模式
36                 PreparedStatement pstmt = conn.prepareStatement(sql
37                         , ResultSet.TYPE_SCROLL_INSENSITIVE
38                         , ResultSet.CONCUR_UPDATABLE);
39                 ResultSet rs = pstmt.executeQuery() ) {
40                     rs.last();
41                     int rowCount = rs.getRow();
42                     for (int i = rowCount; i > 0 ; i--) {
43                         rs.absolute(i);
44                         System.out.println("打印第 "+i+" 行: "+rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
45                         //修改当前行,第2列和第3列的值
46                         rs.updateString(2, "学生名"+i);
47                         rs.updateString(3, "学生名"+(i+1));
48                         //提交修改
49                         rs.updateRow();
50                     }
51                 }
52     }
53     
54     public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, IOException, SQLException {
55         ResultSetTest rt = new ResultSetTest();
56         rt.initParam("mysql.ini");
57         rt.query("select * from jdbc_test");
58     }
59 }

执行结果如下,

 1 打印第 27 行: 27    学生名27    学生名28
 2 打印第 26 行: 26    学生名26    学生名27
 3 打印第 25 行: 25    学生名25    学生名26
 4 打印第 24 行: 24    学生名24    学生名25
 5 打印第 23 行: 23    学生名23    学生名24
 6 打印第 22 行: 22    学生名22    学生名23
 7 打印第 21 行: 21    学生名21    学生名22
 8 打印第 20 行: 20    学生名20    学生名21
 9 打印第 19 行: 19    学生名19    学生名20
10 打印第 18 行: 18    学生名18    学生名19
11 打印第 17 行: 17    学生名17    学生名18
12 打印第 16 行: 16    学生名16    学生名17
13 打印第 15 行: 15    学生名15    学生名16
14 打印第 14 行: 14    学生名14    学生名15
15 打印第 13 行: 13    学生名13    学生名14
16 打印第 12 行: 12    学生名12    学生名13
17 打印第 11 行: 11    学生名11    学生名12
18 打印第 10 行: 10    学生名10    学生名11
19 打印第 9 行: 9    学生名9    学生名10
20 打印第 8 行: 8    学生名8    学生名9
21 打印第 7 行: 7    学生名7    学生名8
22 打印第 6 行: 6    学生名6    学生名7
23 打印第 5 行: 5    学生名5    学生名6
24 打印第 4 行: 4    学生名4    学生名5
25 打印第 3 行: 3    学生名3    学生名4
26 打印第 2 行: 2    学生名2    学生名3
27 打印第 1 行: 1    学生名1    学生名2