JDBC的结果集

以下内容引用自http://wiki.jikexueyuan.com/project/jdbc/result-sets.html

SQL语句从数据库查询中获取数据,并将数据返回到结果集中。SELECT语句是一种标准的方法,它从一个数据库中选择行记录,并显示在一个结果集中。java.sql.ResultSet接口表示一个数据库查询的结果集。

一个ResultSet对象控制一个光标指向当前行的结果集。术语“结果集”是指包含在ResultSet对象中的行和列的数据。

ResultSet接口的方法可细分为三类:

  • 导航方法(Navigational):用于移动光标。
  • 获取方法(Get):用于查看当前行被光标所指向的列中的数据。
  • 更新方法(Update):用于更新当前行的列中的数据。这些更新也会更新数据库中的数据。

光标的移动基于ResultSet的属性。用相应的语句生成ResultSet对象时,同时生成ResultSet的属性。

JDBC提供了连接方法通过下列创建语句来生成所需的ResultSet对象:

  • createStatement(int RSType, int RSConcurrency);
  • prepareStatement(String SQL, int RSType, int RSConcurrency);
  • prepareCall(String sql, int RSType, int RSConcurrency);

第一个参数表示ResultSet对象的类型,第二个参数是两个ResultSet常量之一,该常量用于判断该结果集是只读的还是可修改的。

一、ResultSet的类型

可能的RSType如下所示。如果不指定ResultSet类型,将自动获得的值是TYPE_FORWARD_ONLY。

类型 描述
ResultSet.TYPE_FORWARD_ONLY 光标只能在结果集中向前移动。
ResultSet.TYPE_SCROLL_INSENSITIVE 光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作不会影响结果集的数据。
ResultSet.TYPE_SCROLL_SENSITIVE. 光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作会影响结果集的数据。

二、ResultSet的并发性

RSConcurrency的值如下所示,如果不指定并发类型,将自动获得的值是CONCUR_READ_ONLY。

并发性 描述
ResultSet.CONCUR_READ_ONLY 创建一个只读结果集,这是默认的值。
ResultSet.CONCUR_UPDATABLE 创建一个可修改的结果集。

到目前为止示例可以如下所示,可以写成初始化一个Statement对象来创建一个只能前进,而且只读的ResultSet对象:

try {
   Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
}
catch(Exception ex) {
   ....
}
finally {
   ....
}

三、导航结果集

在ResultSet接口中包括如下几种方法涉及移动光标:

方法 描述
public void beforeFirst() throws SQLException
将光标移动到第一行之前。

public void afterLast() throws SQLException
将光标移动到最后一行之后。

public boolean first() throws SQLException
将光标移动到第一行。

public void last() throws SQLException
将光标移动到最后一行。

public boolean absolute(int row) throws SQLException
将光标移动到指定的第row行。

public boolean relative(int row) throws SQLException
将光标移动到当前指向的位置往前或往后第row行的位置。

public boolean previous() throws SQLException
将光标移动到上一行,如果超过结果集的范围则返回false。

public boolean next() throws SQLException
将光标移动到下一行,如果是结果集的最后一行则返回false。

public int getRow() throws SQLException
返回当前光标指向的行数的值。

public void moveToInsertRow() throws SQLException
将光标移动到结果集中指定的行,可以在数据库中插入新的一行。当前光标位置将被记住。

public void moveToCurrentRow() throws SQLException
如果光标处于插入行,则将光标返回到当前行,其他情况下,这个方法不执行任何操作。

示例:

//STEP 1. Import required packages
import java.sql.*;

public class JDBCExample {
    // JDBC driver name and database URL
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC";

    // Database credentials
    static final String USER = "root";
    static final String PASS = "root";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            // STEP 2: Register JDBC driver
            Class.forName("com.mysql.jdbc.Driver");

            // STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // STEP 4: Execute a query to create statment with
            // required arguments for RS example.
            System.out.println("Creating statement...");
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            String sql;
            sql = "SELECT id, first, last, age FROM Employees";
            ResultSet rs = stmt.executeQuery(sql);

            // Move cursor to the last row.
            System.out.println("Moving cursor to the last...");
            rs.last();

            // STEP 5: Extract data from result set
            System.out.println("Displaying record...");
            // Retrieve by column name
            int id = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);

            // Move cursor to the first row.
            System.out.println("Moving cursor to the first row...");
            rs.first();

            // STEP 6: Extract data from result set
            System.out.println("Displaying record...");
            // Retrieve by column name
            id = rs.getInt("id");
            age = rs.getInt("age");
            first = rs.getString("first");
            last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);
            // Move cursor to the first row.

            System.out.println("Moving cursor to the next row...");
            rs.next();

            // STEP 7: Extract data from result set
            System.out.println("Displaying record...");
            id = rs.getInt("id");
            age = rs.getInt("age");
            first = rs.getString("first");
            last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);

            // STEP 8: Clean-up environment
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            // Handle errors for JDBC
            se.printStackTrace();
        } catch (Exception e) {
            // Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            // finally block used to close resources
            try {
                if (stmt != null)
                    stmt.close();
            } catch (SQLException se2) {
            } // nothing we can do
            try {
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            } // end finally try
        } // end try
        System.out.println("Goodbye!");
    }// end main
}// end JDBCExample

这将产生如下所示结果:

四、查看结果集

ResultSet接口中含有几十种从当前行获取数据的方法。

每个可能的数据类型都有一个get方法,并且每个get方法有两个版本:

  • 一个需要列名。
  • 一个需要列的索引。

例如,如果想查看的列包含一个int类型,需要在ResultSet中调用getInt()方法:

方法 描述
public int getInt(String columnName) throws SQLException
返回当前行中名为columnName的列的int值。

public int getInt(int columnIndex) throws SQLException
返回当前行中指定列的索引的int值。列索引从1开始,意味着行中的第一列是1 ,第二列是2 ,以此类推。

同样的,在ResultSet接口中还有获取八个Java原始类型的get方法,以及常见的类型,比如java.lang.String,java.lang.Object和java.net.URL。

也有用于获取SQL数据类型java.sql.Date,java.sql.Time,java.sql.Timestamp,java.sql.Clob,java.sql.Blob中的方法。查看官方Java文档可以了解使用这些SQL数据类型的更多的信息。

示例:

//STEP 1. Import required packages
import java.sql.*;

public class JDBCExample2 {
    // JDBC driver name and database URL
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC";

    // Database credentials
    static final String USER = "root";
    static final String PASS = "root";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            // STEP 2: Register JDBC driver
            Class.forName("com.mysql.jdbc.Driver");

            // STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // STEP 4: Execute a query to create statment with
            // required arguments for RS example.
            System.out.println("Creating statement...");
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            String sql;
            sql = "SELECT id, first, last, age FROM Employees";
            ResultSet rs = stmt.executeQuery(sql);

            // Move cursor to the last row.
            System.out.println("Moving cursor to the last...");
            rs.last();

            // STEP 5: Extract data from result set
            System.out.println("Displaying record...");
            // Retrieve by column name
            int id = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);

            // Move cursor to the first row.
            System.out.println("Moving cursor to the first row...");
            rs.first();

            // STEP 6: Extract data from result set
            System.out.println("Displaying record...");
            // Retrieve by column name
            id = rs.getInt("id");
            age = rs.getInt("age");
            first = rs.getString("first");
            last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);
            // Move cursor to the first row.

            System.out.println("Moving cursor to the next row...");
            rs.next();

            // STEP 7: Extract data from result set
            System.out.println("Displaying record...");
            id = rs.getInt(1);//The first column index
            age = rs.getInt("age");
            first = rs.getString("first");
            last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);

            // STEP 8: Clean-up environment
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            // Handle errors for JDBC
            se.printStackTrace();
        } catch (Exception e) {
            // Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            // finally block used to close resources
            try {
                if (stmt != null)
                    stmt.close();
            } catch (SQLException se2) {
            } // nothing we can do
            try {
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            } // end finally try
        } // end try
        System.out.println("Goodbye!");
    }// end main
}// end JDBCExample

这将产生如下所示结果:

五、更新的结果集

ResultSet接口包含了一系列的更新方法,该方法用于更新结果集中的数据。

用get方法可以有两个更新方法来更新任一数据类型:

  • 一个需要列名。
  • 一个需要列的索引。

例如,要更新一个结果集的当前行的String列,可以使用任一如下所示的updateString()方法:

方法 描述
public void updateString(int columnIndex, String s) throws SQLException
将指定列的字符串的值改为s。

public void updateString(String columnName, String s) throws SQLException
类似于前面的方法,不同之处在于指定的列是用名字来指定的,而不是它的索引。

八个原始数据类型都有其更新方法,比如String,Object,URL,和在java.sql包中的SQL数据类型。

更新结果集中的行将改变当前行的列中的ResultSet对象,而不是基础数据库中的数据。要更新数据库中一行的数据,需要调用以下的任一方法:

方法 描述
public void updateRow()
通过更新数据库中相对应的行来更新当前行。

public void deleteRow()
从数据库中删除当前行。

public void refreshRow()
在结果集中刷新数据,以反映数据库中最新的数据变化。

public void cancelRowUpdates()
取消对当前行的任何修改。

public void insertRow()
在数据库中插入一行。本方法只有在光标指向插入行的时候才能被调用。

示例:

//STEP 1. Import required packages
import java.sql.*;

public class JDBCExample3 {
    // JDBC driver name and database URL
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC";

    // Database credentials
    static final String USER = "root";
    static final String PASS = "root";

    public static void main(String[] args) {
        Connection conn = null;
        try {
            // STEP 2: Register JDBC driver
            Class.forName("com.mysql.jdbc.Driver");

            // STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // STEP 4: Execute a query to create statment with
            // required arguments for RS example.
            System.out.println("Creating statement...");
            Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
            // STEP 5: Execute a query
            String sql = "SELECT id, first, last, age FROM Employees";
            ResultSet rs = stmt.executeQuery(sql);

            System.out.println("List result set for reference....");
            printRs(rs);

            // STEP 6: Loop through result set and add 5 in age
            // Move to BFR postion so while-loop works properly
            rs.beforeFirst();
            // STEP 7: Extract data from result set
            while (rs.next()) {
                // Retrieve by column name
                int newAge = rs.getInt("age") + 5;
                rs.updateDouble("age", newAge);
                rs.updateRow();
            }
            System.out.println("List result set showing new ages...");
            printRs(rs);
            // Insert a record into the table.
            // Move to insert row and add column data with updateXXX()
            System.out.println("Inserting a new record...");
            rs.moveToInsertRow();
            rs.updateInt("id", 104);
            rs.updateString("first", "John");
            rs.updateString("last", "Paul");
            rs.updateInt("age", 40);
            // Commit row
            rs.insertRow();

            System.out.println("List result set showing new set...");
            printRs(rs);

            // Delete second record from the table.
            // Set position to second record first
            rs.absolute(2);
            System.out.println("List the record before deleting...");
            // Retrieve by column name
            int id = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);

            // Delete row
            rs.deleteRow();
            System.out.println("List result set after deleting one records...");
            printRs(rs);

            // STEP 8: Clean-up environment
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            // Handle errors for JDBC
            se.printStackTrace();
        } catch (Exception e) {
            // Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            // finally block used to close resources
            try {
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            } // end finally try
        } // end try
        System.out.println("Goodbye!");
    }// end main

    public static void printRs(ResultSet rs) throws SQLException {
        // Ensure we start with first row
        rs.beforeFirst();
        while (rs.next()) {
            // Retrieve by column name
            int id = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);
        }
        System.out.println();
    }// end printRs()
}// end JDBCExample

这将产生如下所示结果:

测试工程:https://github.com/easonjim/5_java_example/tree/master/jdbcbasics/test2

时间: 2024-10-17 05:56:17

JDBC的结果集的相关文章

com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行

参考博客com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行 java获取结果集,if(rs!=null),和while(rs.next())区别  com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行. st = conn.createStatement(); ResultSet rs = st.executeQuery(sql); if(rs!=null) {//rs.

JDBC 入门 - 结果集

ResultSet (结果集) RSType 和 RSConcurrency 当对数据库进行查询操作的时候, 数据库返回的数据通过 ResultSet 接口获取. ResultSet 内部管理了一个 cursor(游标), cursor 指向当前要读的数据, ResultSet 提供了以下三类接口: 游标移动接口, 用来操作移动游标. 获取数据接口, 用来从当前游标指向位置的数据 更新数据接口, 用来更新当前游标指向位置的数据, 并可以更改对应数据库中的数据. ResultSet 的类型: 在创

将JDBC ResultSet结果集变成List

private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); public String queryAll() { Connection conn = null; Statement sta = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); con

关于YMP框架JDBC查询结果集自定义处理方法

final String _sql = "SELECT u.name as name, u.age, u.type, u.birth FROM ym_user u WHERE u.age > ?, u.type = ?"; // 1. 将SQL查询的结果集采用数组的形式封装 List<Object[]> _results = JDBC.openSession(new ISessionExecutor<List<Object[]>>() { pu

将JDBC ResultSet结果集转成List

背景: 之前想要将数据库中的记录转化成List,需要对ResultSet中的数据根据不用的数据类型,用get方法进行获取: 现在通过使用ResultSet中的元数据信息,自动根据数据类型进行相关数据的取出: 避免了每次判断类型这样的繁琐操作: 实现: private static List<List<Object>> list = new ArrayList<List<Object>>(); public static String queryAll() {

完整的jdbc查询结果集编码

1 public static ArrayList<HashMap<String,Object>> query(Connection conn,String sql, Object[] paras) throws Exception { 2 PreparedStatement statement = null; 3 ResultSet ss = null; 4 String str = "";//打日志使用 5 ArrayList<HashMap<S

JDBC ResultSet 可更新的结果集

接着上一篇:可滚动的结果集: 1)com.microsoft.sqlserver.jdbc.SQLServerException: 结果集不可更新. 当concurrency设置为:ResultSet.CONCUR_READ_ONLY(默认)时,结果集不能更新数据,否则会报 SQLServerException 示例: statement = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_R

JDBC ResultSet 可滚动的结果集

可滚动的结果集 1)com.microsoft.sqlserver.jdbc.SQLServerException: 只进结果集不支持请求的操作. 当type设置为:ResultSet.TYPE_FORWARD_ONLY(默认)时,游标是不能任意移动的,只能逐步向前,否则会报 SQLServerException 示例: statement = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_XXX)

集算器替代存储过程实现报表数据源

存储过程是SQL语句和流程控制语句的集合,常用来把一个复杂的计算目标分解为多个简单的计算步骤.虽然以复杂性换来了灵活性,但SQL语句固有的缺点仍然体现在存储过程中,比如:分步不彻底.数据无序.缺乏集合.缺乏引用,之前我们也分析过存储过程作为报表数据源的利弊,可点击这里查看. 集算器解决了存储过程的上述缺陷,降低了对开发人员的技术要求,是存储过程理想的替代工具. 报表例子说明 某电信产品厂商有一张报表,主要目的是分析优势产品的销售额.销量.环比等指标,其中优势产品的定义是"在每个州的销量均在前10