JDBC学习(四) --- ResultSet结果集

 ResultSet是JDBC中的一个接口,用于表示由数据库执行查询操作后返回的结果集。使用ResultSet接口,可以访问查询结果的当前行,并可以逐行移动结果集,从而让我们能够对结果集中的每行数据进行处理。在JDBC中,ResultSet接口由Statement.executeQuery()方法或PreparedStatement.executeQuery()方法返回

 使用ResultSet接口时,通常是以以下步骤进行操作:

  1. 将光标移动到结果集的第一行
  2. 访问当前行的数据
  3. 在结果集中移动光标
  4. 释放资源

 现给出一个完整的基础示例:

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JdbcResultSetExample {
    static String user = "YourName";
    static String password = "YourPassword";
    static String url = "jdbc:mysql://localhost:3306/jdbcdata";
    static String className = "com.mysql.cj.jdbc.Driver";
    // 获取数据库连接操作
    public Connection getJDBCConnection() throws Exception{
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, user, password);
        if(connection != null) {
            return connection;
        }
        return null;
    }

    @Test
    public void resultSetTest() throws Exception{
        // 获取连接
        Connection conn = getJDBCConnection();
        if(conn != null){
            // 待执行的SQL语句
            String sql = "select job_id, job_title, min_salary, max_salary from jobs where min_salary > ? and max_salary < ?";
            // 预编译
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            // 设置参数
            preparedStatement.setInt(1,8000);
            preparedStatement.setInt(2,20000);
            // 执行SQL语句,获取结果集
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                // 获取一个对象的信息
                String job_id = resultSet.getString("job_id");
                String job_title = resultSet.getString(2);
                int min_salary = resultSet.getInt("min_salary");
                int max_salary = resultSet.getInt(4);
                // 输出
                System.out.println(job_id + " " + job_title + " " + min_salary + " " + max_salary) ;
            }
            // 关闭
            conn.close();
            preparedStatement.close();
            resultSet.close();
        }
    }
}

 运行结果:

AC_MGR Accounting Manager 8200 16000
FI_MGR Finance Manager 8200 16000
MK_MAN Marketing Manager 9000 15000

结果集

 SQL语句从数据库中查询获取数据并将数据返回到结果集中。SELECT语句就是一个经典例子,它从一个数据库中选择行记录,并显示在一个结果集中。ResultSet接口就表示一个数据库查询的结果集

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

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

  • 导航方法:用于移动光标
  • 获取方法:查看被光标所指向的当前行的列中的数据。
  • 更新方法:用于更新当前行的列中的数据,更新的同时也会影响到数据库中的数据。

光标的移动是基于ResultSet属性。我们在生成ResultSet对象的同时也会生成ResultSet属性。我们通过连接对象所提供的下述方法即可获得ResultSet对象:

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

 上述参数中的RSType用于表示返回的结果集类型,具体见下表:

结果集类型

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

结果集并发性

RSConcurrency参数用于指定结果集的并发类型,具体见下表:

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

结果集导航

S.N.方法 & 描述
1public void beforeFirst() throws SQLException
将光标移动到第一行之前。
2public void afterLast() throws SQLException
将光标移动到最后一行之后。
3public boolean first() throws SQLException
将光标移动到第一行。
4public void last() throws SQLException
将光标移动到最后一行。
5public boolean absolute(int row) throws SQLException
将光标移动到指定的第 row 行。
6public boolean relative(int row) throws SQLException
将光标移动到当前指向的位置往前或往后第 row 行的位置。
7public boolean previous() throws SQLException
将光标移动到上一行,如果超过结果集的范围则返回 false。
8public boolean next() throws SQLException
将光标移动到下一行,如果是结果集的最后一行则返回 false。(常用)
9public int getRow() throws SQLException
返回当前光标指向的行数的值。
10public void moveToInsertRow() throws SQLException
将光标移动到结果集中指定的行,可以在数据库中插入新的一行。当前光标位置将被记住。
11public void moveToCurrentRow() throws SQLException
如果光标处于插入行,则将光标返回到当前行,其他情况下,这个方法不执行任何操作。

 例如之前介绍的例子:

ResultSet resultSet = preparedStatement.executeQuery();
// 不断导航到当前光标的下一行,直到光标达到最后一行
while (resultSet.next()){
    // 具体操作
}

结果集查看

 ResultSet接口中含有几十种从当前行获取数据的方法,每个可能的数据类型,ResultSet接口都有一个get方法用于获取数据,并且每个get方法都有两种调用方式:

  • 通过列名
  • 通过列的索引,从1开始

 例如上面介绍的例子:


String sql = "select job_id, job_title, min_salary, max_salary from jobs where min_salary > ? and max_salary < ?";

while (resultSet.next()){
    // 获取一个对象的信息
    String job_id = resultSet.getString("job_id"); // 通过列名获取数据
    String job_title = resultSet.getString(2);// 通过列的索引
    int min_salary = resultSet.getInt("min_salary");
    int max_salary = resultSet.getInt(4);
    // 输出
    System.out.println(job_id + " " + job_title + " " + min_salary + " " + max_salary) ;
}

结果集的更新

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

 与结果集的get方法一样,结果集的更新update方法也有两种调用方式:

  • 通过列名
  • 通过列的索引

 例如要更新当前行的String列的数据,可以使用下面两种方法进行更新或修改:

S.N.方法 & 描述
1public void updateString(int columnIndex, String s) throws SQLException
将指定列的字符串的值改为 s。
2public void updateString(String columnName, String s) throws SQLException
类似于前面的方法,不同之处在于指定的列是用名字来指定的,而不是它的索引。

 同样的,要更新一个int类型的列,调用updateInt方法就行了。但上述所提到的更新方式只能修改结果集中的数据,并不会影响数据库中的数据,要想修改数据库中的数据,可以使用下述几个方法:

S.N.方法 & 描述
1public void updateRow()
通过更新数据库中相对应的行来更新当前行。
2public void deleteRow()
从数据库中删除当前行。
3public void refreshRow()
在结果集中刷新数据,以反映数据库中最新的数据变化。
4public void cancelRowUpdates()
取消对当前行的任何修改。
5public void insertRow()
在数据库中插入一行。本方法只有在光标指向插入行的时候才能被调用。

练习

 练习使用的都是employess表,数据库的数据在JDBC学习一中已给出,答案在最后的所有代码里。

  • 查询薪资大于等于10000的所有员工的姓名first_name和last_name、电话号码phone_number和salary
  • 随机生成(1~250)员工id(employee_id),若员工存在,则将该员工的薪资提高10%,并输出提高前和提高后的信息(fist_name,last_name,salary,email,phone_number),否则,输出“No information about (此处补充输入的ID) was found in the database”
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Random;
import java.util.Scanner;


public class JdbcResultSetExample {
    static String user = "YourName";
    static String password = "YourPassword";
    static String url = "jdbc:mysql://localhost:3306/jdbcdata";
    static String className = "com.mysql.cj.jdbc.Driver";
    public Connection getJDBCConnection() throws Exception{
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, user, password);
        if(connection != null) {
            return connection;
        }
        return null;
    }

    @Test
    public void resultSetTest() throws Exception{
        // 获取连接
        Connection conn = getJDBCConnection();
        if(conn != null){
            // 待执行的SQL语句
            String sql = "select job_id, job_title, min_salary, max_salary from jobs where min_salary > ? and max_salary < ?";
            // 预编译
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            // 设置参数
            preparedStatement.setInt(1,8000);
            preparedStatement.setInt(2,20000);
            // 执行SQL语句,获取结果集
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                // 获取一个对象的信息
                String job_id = resultSet.getString("job_id");
                String job_title = resultSet.getString(2);
                int min_salary = resultSet.getInt("min_salary");
                int max_salary = resultSet.getInt(4);
                // 输出
                System.out.println(job_id + " " + job_title + " " + min_salary + " " + max_salary) ;
            }
            // 关闭
            conn.close();
            preparedStatement.close();
            resultSet.close();
        }
    }

    @Test
    public void resultSetExample1() throws Exception{
        /*
        查询薪资大于等于10000的所有员工的姓名first_name和last_name、电话号码phone_number和salary
         */
        Connection conn = getJDBCConnection();

        if(conn != null){
            String sql = "SELECT first_name, last_name, phone_number, salary FROM employees WHERE salary >= ?";

            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            if(preparedStatement != null){

                preparedStatement.setInt(1,10000);
                ResultSet resultSet = preparedStatement.executeQuery();
                if(resultSet != null){
                    while (resultSet.next()){
                        String first_name = resultSet.getString("first_name");
                        String last_name =resultSet.getString("last_name");
                        String phone_number = resultSet.getString("phone_number");
                        int ansSalary = resultSet.getInt("salary");
                        System.out.println(first_name + "·" + last_name + " " + phone_number + " " + ansSalary);
                    }
                    resultSet.close();
                    preparedStatement.close();
                    conn.close();
                }
            }
        }
    }

    @Test
    public void resultSetExample2() throws Exception{
        /*
        随机生成(1~250)员工id(employee_id),若员工存在,则将该员工的薪资提高10%,并输出提高前和提高后的信息(fist_name,last_name,salary,email,phone_number),
        否则,输出“No information about (此处补充输入的ID) was found in the database”
         */
        Connection conn = getJDBCConnection();
        if(conn != null){
            // 待执行的SQL语句
            String sql = "select * from employees where employee_id = ?";
            PreparedStatement preparedStatement = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
            if(preparedStatement != null){
                int id = 100 +  new Random().nextInt(151);
//                System.out.println(id + "-------");
                preparedStatement.setInt(1,id);
                ResultSet resultSet = preparedStatement.executeQuery();

                if(resultSet != null){

                    while (resultSet.next()){

                        String first_name = resultSet.getString("first_name");
                        String last_name = resultSet.getString("last_name");
                        int salary = resultSet.getInt("salary");
                        String email = resultSet.getString("email");
                        String phone_number = resultSet.getString("phone_number");
                        System.out.println(first_name + " " + last_name + " " + salary + " " + email + " " + phone_number);
                        resultSet.updateInt("salary",salary + (int)((double)salary * 0.1));
                        resultSet.updateRow();
                        int salaryAfter = resultSet.getInt("salary");
                        System.out.println(first_name + " " + last_name + " " + salaryAfter + " " + email + " " + phone_number);
                    }
                    resultSet.close();
                    preparedStatement.close();
                    conn.close();
                }else{
                    System.out.println("No information about " + id +" was found in the database");
                    preparedStatement.close();
                    conn.close();
                }
            }

        }
    }

    @Test
    public void test(){
        Scanner scan = new Scanner(System.in);
        int i = scan.nextInt();
//        int i = 32;
        System.out.println(i);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PG Thinker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值