Result Set

Данные, полученные в результате SQL -запроса, возвращаются в виде множества результатов, которые хранятся в сущности под названием Result Set.

Стандартный способ получить записи из нашей базе данных (далее – БД) – это применение ключевого слова SELECT. Стандартный способ просмотреть эти данные – это использовать Result set.

Интерфейс java.sql.ResultSet представляет собой множество результатов запроса в БД.

Экземпляр ResultSet имеет указатель, который указывает на текущую строку в полученном множестве.

Все методы интерфейса java.sql.ResultSet можно разделить на три большие группы:

  • Методы получения данных.

    Эти методы используются для просмотра данных конкретной записи, на которую ссылается указатель.

  • Методы изменения данных.

    Методы этой группы используются для изменения данных текущей записи. Эти изменения передаются в используемую БД.

  • Методы навигации.

    Эти методы используются для перемещения указателя.

Курсор двигается на основе свойств ResultSet. Эти свойства указываются при создании экземпляра ResultSet.

Для определения этих свойств используются следующие методы:

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

Аргумент RSType определяет тип ResultSet, а второй определяет, используется ли экземпляр ResultSet только для чтения или для чтения и изменения также.


Типы ResultSet

Возможные типы ResultSet приведены ниже. Тип TYPE_FORWARD_ONLY используется по умолчанию.

Рассмотрим эти типы:

  • ResultSet.TYPE-FORWARD_ONLY


    Указатель двигается только вперед по множеству полученных результатов.

    .

  • ResultSet.TYPE_SCROLL_INTENSIVE

    Указатель может двигаться вперед и назад и не чувствителен к изменениям в БД, которые сделаны другими пользователями после того, как ResultSet был создан.

  • ResultSet.TYPE_SCROLL_SENSITIVE

    Указатель может двигаться вперед и назад и чувствителен к изменениям в БД, которые сделаны другими пользователями после того, как ResultSet был создан.


Доступ ResultSet

По умолчанию RSConcurrency экземпляра ResultSet установлен тип CONCUR_READ_ONLY, т.е. только для чтения.

Всего существует два типа этого параметра:

  • ResultSet.CONCUR_READ_ONLY

    Создает экземпляр ResultSet только для чтения. Устанавливается по умолчанию.

  • ResultSet.CONCUR_UPDATABLE

    Создает экземпляр ResultSet, который может изменять данные.

В виде кода создание экземпляра ResultSet с необходимыми параметрами выглядит таким образом:

try {
            statement = connection.createStatement(
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_READ_ONLY
            );
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            /*do some job*/
        }

Навигация по ResultSet

В интерфейсе java.sql.ResultSet существует несколько методов для перемещения указателя.

Некоторые из них приведены ниже:

  • public void beforeFirst () throws SQLException

    Перемещает указатель на место перед первым рядом.

  • public void afterLast () throws SQLException

    Перемещает указатель на место после крайнего ряда.

  • public boolean first () throws SQLException

    Перемещает указатель на первый ряд.

  • public boolean last () throws SQLException

    Перемещает указатель на крайний ряд.

  • public boolean previous () throws SQLException

    Перемещает указатель на предыдущий ряд. Возвращает
    false
    , если предыдущий ряд находится за пределами множества результатов.

  • public boolean next () throws SQLException

    Перемещает указатель на следующий ряд. Возвращает
    false
    , если следующий ряд находится за пределами множества результатов.

  • public void absolute (int row) throws SQLException

    Перемещает указатель на указанный ряд.

  • public void relative (int row) throws SQLException

    Перемещает указатель на указанное количество рядов от текущего

  • public int getRow () throws SQLException

    Возвращает номер ряда, на который в данный момент указывает курсор.

  • public void moveToInsertRow () throws SQLException

    Перемещает указатель на ряд в полученном множестве, который может быть использован для того, чтобы добавить новую запись в БД. Текущее положение указателя запоминается.

  • public void moveToCurrentRow () throws SQLExcpetion

    Возвращает указатель обратно на текущий ряд в случае, если указатель ссылается на ряд, в который в данный момент добавляются данные.

Для понимания того, как это работает на практике, рассмотрим пример простого приложения.

import java.sql.*;

public class ResultSetNavigationDemo {
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS";

    static final String USER = "ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ";
    static final String PASSWORD = "ВАШ_ПАРОЛЬ";

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Connection connection = null;
        Statement statement = null;

        Class.forName(JDBC_DRIVER);

        connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD);

        System.out.println("Creating statement...");

        try {
            statement = connection.createStatement(
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_UPDATABLE
            );
            String SQL = "SELECT * FROM developers";
            ResultSet resultSet = statement.executeQuery(SQL);

            System.out.println("Moving cursor to the last position...");
            resultSet.last();

            System.out.println("Getting record...");
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String specialty = resultSet.getString("specialty");
            int salary = resultSet.getInt("salary");

            System.out.println("Last record in result set:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Moving cursor to previous row...");
            resultSet.previous();

            System.out.println("Getting record...");
            id = resultSet.getInt("id");
            name = resultSet.getString("name");
            specialty = resultSet.getString("specialty");
            salary = resultSet.getInt("salary");

            System.out.println("Previous record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Moving cursor to the first row...");
            resultSet.first();

            System.out.println("Getting record...");
            id = resultSet.getInt("id");
            name = resultSet.getString("name");
            specialty = resultSet.getString("specialty");
            salary = resultSet.getInt("salary");

            System.out.println("First record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Adding record...");
            SQL = "INSERT INTO developers VALUES (5, 'Mike', 'PHP', 1500)";
            statement.executeUpdate(SQL);

            SQL = "SELECT * FROM developers";
            resultSet = statement.executeQuery(SQL);
            resultSet.last();

            System.out.println("Getting record...");
            id = resultSet.getInt("id");
            name = resultSet.getString("name");
            specialty = resultSet.getString("specialty");
            salary = resultSet.getInt("salary");

            System.out.println("Last record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");


            System.out.println("Full list of records:");
            SQL = "SELECT * FROM developers";
            resultSet = statement.executeQuery(SQL);

            while (resultSet.next()) {
                id = resultSet.getInt("id");
                name = resultSet.getString("name");
                specialty = resultSet.getString("specialty");
                salary = resultSet.getInt("salary");

                System.out.println("id: " + id);
                System.out.println("Name: " + name);
                System.out.println("Specialty: " + specialty);
                System.out.println("Salary: $" + salary);
                System.out.println("\n=========================\n");

            }


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
             if (statement != null) {
                statement.close();
            }
            if(connection!=null){
                connection.close();
            }
        }
    }
}

В результате работы программы получим следующий результат:

/*Some System Messages*/

Creating statement...
Moving cursor to the last position...
Getting record...
Last record in result set:
id: 4
Name: Eugene
Specialty: Java
Salary: $3000

=========================

Moving cursor to previous row...
Getting record...
Previous record:
id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $2000

=========================

Moving cursor to the first row...
Getting record...
First record:
id: 1
Name: Proselyte
Specialty: Java
Salary: $3000

=========================

Adding record...
Getting record...
Last record:
id: 5
Name: Mike
Specialty: PHP
Salary: $1500

=========================

Full list of records:
id: 1
Name: Proselyte
Specialty: Java
Salary: $3000

=========================

id: 2
Name: Peter
Specialty: C++
Salary: $3000

=========================

id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $2000

=========================

id: 4
Name: Eugene
Specialty: Java
Salary: $3000

=========================

id: 5
Name: Mike
Specialty: PHP
Salary: $1500

=========================

Просмотр результатов ResultSet

Для получения и редактирования данных в интерфейсе ResultSet существует множество методов.

Мы можем получить данные как по имени, так и индексу:

  • public int getInt (int columnIndex) throws SQLException

    Возвращает номер текущего ряда с указанным индексом колонки. Индексы начинаются с 1. Т.е. первая – 1, вторая – 2 и т.д.

  • public int getInt (String columnName) throws SQLException

    Возвращает целое число в текущем ряду с колонкой с именем, переданном в параметре columnName.

Существуют также методы для получения определенных типов данных SQL (java.sql.Time, java.sql.Date и т.д.).

Для понимания того, как это работает на практике, рассмотрим следующий пример:

import java.sql.*;

public class ResultSetViewDemo {
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS";

    static final String USER = "ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ";
    static final String PASSWORD = "ВАШ_ПАРОЛЬ";

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Connection connection = null;
        Statement statement = null;

        Class.forName(JDBC_DRIVER);

        connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD);

        System.out.println("Creating statement...");

        try {
            statement = connection.createStatement(
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_UPDATABLE
            );
            String SQL = "SELECT * FROM developers";
            ResultSet resultSet = statement.executeQuery(SQL);

            System.out.println("Moving cursor to the last position...");
            resultSet.last();

            System.out.println("Getting record (by name)...");
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String specialty = resultSet.getString("specialty");
            int salary = resultSet.getInt("salary");

            System.out.println("Last record in result set:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Moving cursor to previous row...");
            resultSet.previous();

            System.out.println("Getting record...");
            id = resultSet.getInt("id");
            name = resultSet.getString("name");
            specialty = resultSet.getString("specialty");
            salary = resultSet.getInt("salary");

            System.out.println("Previous record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Moving cursor to the first row...");
            resultSet.first();

            System.out.println("Getting record...");
            id = resultSet.getInt("id");
            name = resultSet.getString("name");
            specialty = resultSet.getString("specialty");
            salary = resultSet.getInt("salary");

            System.out.println("First record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");

            System.out.println("Adding record...");
            SQL = "INSERT INTO developers VALUES (5, 'Mike', 'PHP', 1500)";
            statement.executeUpdate(SQL);

            SQL = "SELECT * FROM developers";
            resultSet = statement.executeQuery(SQL);
            resultSet.last();

            System.out.println("Getting record (by index)...");
            id = resultSet.getInt(1);
            name = resultSet.getString(2);
            specialty = resultSet.getString(3);
            salary = resultSet.getInt(4);

            System.out.println("Last record:");
            System.out.println("id: " + id);
            System.out.println("Name: " + name);
            System.out.println("Specialty: " + specialty);
            System.out.println("Salary: $" + salary);
            System.out.println("\n=========================\n");


            System.out.println("Full list of records (by name):");
            SQL = "SELECT * FROM developers";
            resultSet = statement.executeQuery(SQL);

            while (resultSet.next()) {
                id = resultSet.getInt("id");
                name = resultSet.getString("name");
                specialty = resultSet.getString("specialty");
                salary = resultSet.getInt("salary");

                System.out.println("id: " + id);
                System.out.println("Name: " + name);
                System.out.println("Specialty: " + specialty);
                System.out.println("Salary: $" + salary);
                System.out.println("\n=========================\n");

            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

В результате работы программы получим следующий результат:

/*Some System Messages*/

Creating statement...
Moving cursor to the last position...
Getting record (by name)...
Last record in result set:
id: 4
Name: Eugene
Specialty: Java
Salary: $3000

=========================

Moving cursor to previous row...
Getting record...
Previous record:
id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $2000

=========================

Moving cursor to the first row...
Getting record...
First record:
id: 1
Name: Proselyte
Specialty: Java
Salary: $3000

=========================

Adding record...
Getting record (by index)...
Last record:
id: 5
Name: Mike
Specialty: PHP
Salary: $1500

=========================

Full list of records (by name):
id: 1
Name: Proselyte
Specialty: Java
Salary: $3000

=========================

id: 2
Name: Peter
Specialty: C++
Salary: $3000

=========================

id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $2000

=========================

id: 4
Name: Eugene
Specialty: Java
Salary: $3000

=========================

id: 5
Name: Mike
Specialty: PHP
Salary: $1500

=========================

Редактирование данных ResultSet

Для редактирования данных в интерфейсе java.sql.ResultSet также разработано множество методов.

Мы можем изменять данные как по имени, так и по индексу колонки:

  • public void updateString (int columnIndex, String s) throws SQLException

    Изменяет строку в указанной колонке.

  • public void updateString (String columnName, String s) throws SQLException

    Изменяет строку в колонке с указанным именем.

Мы также можем работать с рядами в таблице БД:

  • public void insertRow()

    Вставляет запись в таблицу БД. Может быть использован только в том случае, когда указатель ссылается на ряд для вставки.

  • public void updateRow()

    Изменяет текущий ряд в таблице БД.

  • public void deleteRow()

    Удаляет текущий ряд из таблицы БД.

Для понимания того, как это работает на практике, рассмотрим следующий пример.

import java.sql.*;

public class ResultSetUpdateDemo {
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DATABASE_URL = "jdbc:mysql://localhost/PROSELYTE_TUTORIALS";

    static final String USER = "ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ";
    static final String PASSWORD = "ВАШ_ПАРОЛЬ";

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Connection connection = null;
        Statement statement = null;

        Class.forName(JDBC_DRIVER);

        connection = DriverManager.getConnection(DATABASE_URL, USER, PASSWORD);

        System.out.println("Creating statement...");

        try {
            statement = connection.createStatement(
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_UPDATABLE
            );
            String SQL = "SELECT * FROM developers";
            ResultSet resultSet = statement.executeQuery(SQL);

            System.out.println("Initial list of records:");
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String specialty = resultSet.getString("specialty");
                int salary = resultSet.getInt("salary");

                System.out.println("Last record in result set:");
                System.out.println("id: " + id);
                System.out.println("Name: " + name);
                System.out.println("Specialty: " + specialty);
                System.out.println("Salary: $" + salary);
                System.out.println("\n=========================\n");
            }

            System.out.println("Increasing all developer's salary (+ $1,000)...");
            resultSet.first();
            while (resultSet.next()) {
                int newSalary = resultSet.getInt("salary") + 1000;
                resultSet.updateInt("salary", newSalary);
                resultSet.updateRow();
            }

            resultSet.first();
            System.out.println("Final list of records:");
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String specialty = resultSet.getString("specialty");
                int salary = resultSet.getInt("salary");

                System.out.println("id: " + id);
                System.out.println("Name: " + name);
                System.out.println("Specialty: " + specialty);
                System.out.println("Salary: $" + salary);
                System.out.println("\n=========================\n");
            }
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

В результате работы программы получим следующий результат:

Creating statement...
Initial list of records:
Last record in result set:
id: 1
Name: Proselyte
Specialty: Java
Salary: $3000

=========================

Last record in result set:
id: 2
Name: Peter
Specialty: C++
Salary: $3000

=========================

Last record in result set:
id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $2000

=========================

Last record in result set:
id: 4
Name: Eugene
Specialty: Java
Salary: $3000

=========================

Last record in result set:
id: 5
Name: Mike
Specialty: PHP
Salary: $1500

=========================

Increasing all developer's salary (+ $1,000)...
Final list of records:
id: 2
Name: Peter
Specialty: C++
Salary: $4000

=========================

id: 3
Name: AsyaSmile
Specialty: UI/UX
Salary: $3000

=========================

id: 4
Name: Eugene
Specialty: Java
Salary: $4000

=========================

id: 5
Name: Mike
Specialty: PHP
Salary: $2500

=========================

results matching ""

    No results matching ""