← Назад к вопросам
Как называется сущность, которая обладает информацией о следующем элементе в ResultSet
1.0 Junior🔥 61 комментариев
#Другое
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Cursor в ResultSet
Что такое Cursor?
Cursor (курсор) — это сущность в JDBC, которая обладает информацией о текущей позиции и может перемещаться по результатам запроса в ResultSet. Курсор указывает на строку данных и позволяет перемещаться между строками.
Работа с Cursor через ResultSet
import java.sql.*;
public class CursorExample {
public static void main(String[] args) {
String query = "SELECT id, name, email FROM users";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "password");
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(query)) {
// Cursor находится ПЕРЕД первой строкой
while (resultSet.next()) { // next() движет cursor на следующую строку
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
// После цикла cursor находится ПОСЛЕ последней строки
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Методы перемещения Cursor
Основные методы навигации:
resultSet.next(); // Движет cursor на следующую строку
resultSet.previous(); // Движет cursor на предыдущую строку (для прокручиваемых)
resultSet.first(); // Переместиться на первую строку
resultSet.last(); // Переместиться на последнюю строку
resultSet.beforeFirst(); // Переместиться ПЕРЕД первую строку
resultSet.afterLast(); // Переместиться ПОСЛЕ последнюю строку
resultSet.absolute(n); // Переместиться на n-ую строку (1-indexed)
resultSet.relative(n); // Переместиться на n позиций относительно текущей
Пример использования методов навигации
import java.sql.*;
public class CursorNavigation {
public static void main(String[] args) {
String query = "SELECT id, name FROM users";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "pass");
Statement statement = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, // Прокручиваемый ResultSet
ResultSet.CONCUR_READ_ONLY
);
ResultSet rs = statement.executeQuery(query)) {
// Переместиться на последнюю строку
rs.last();
int lastRow = rs.getRow();
System.out.println("Total rows: " + lastRow);
// Переместиться на первую строку
rs.first();
System.out.println("First user: " + rs.getString("name"));
// Переместиться на 3-ю строку
rs.absolute(3);
System.out.println("Third user: " + rs.getString("name"));
// Переместиться на 2 позиции вперёд
rs.relative(2);
System.out.println("User at +2: " + rs.getString("name"));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Типы ResultSet
Тип ResultSet определяет, является ли он прокручиваемым:
// TYPE_FORWARD_ONLY - только вперёд (по умолчанию)
Statement stmt = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY
);
// TYPE_SCROLL_INSENSITIVE - прокручиваемый, не видит изменения
Statement stmt = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY
);
// TYPE_SCROLL_SENSITIVE - прокручиваемый, видит изменения
Statement stmt = connection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE
);
Методы получения информации о Cursor
import java.sql.*;
public class CursorInfo {
public static void main(String[] args) {
String query = "SELECT id, name FROM users";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "pass");
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = statement.executeQuery(query)) {
// Информация о текущей позиции cursor
rs.next();
int currentRow = rs.getRow(); // Номер текущей строки
boolean isFirst = rs.isFirst(); // Курсор на первой строке?
boolean isLast = rs.isLast(); // Курсор на последней строке?
boolean isBeforeFirst = rs.isBeforeFirst(); // Курсор перед первой строкой?
boolean isAfterLast = rs.isAfterLast(); // Курсор после последней строки?
System.out.println("Current row: " + currentRow);
System.out.println("Is first: " + isFirst);
System.out.println("Is last: " + isLast);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Практический пример: Работа с Cursor
import java.sql.*;
public class CursorPractical {
public void iterateTwice(ResultSet rs) throws SQLException {
// Итерация вперёд
System.out.println("=== Forward iteration ===");
rs.beforeFirst();
while (rs.next()) {
System.out.println(rs.getInt("id") + ": " + rs.getString("name"));
}
// Итерация назад
System.out.println("=== Backward iteration ===");
while (rs.previous()) {
System.out.println(rs.getInt("id") + ": " + rs.getString("name"));
}
}
public void getNextElement(ResultSet rs) throws SQLException {
// Проверяем, есть ли следующий элемент
if (rs.next()) {
String nextElement = rs.getString("name");
System.out.println("Next element: " + nextElement);
// Возвращаемся на шаг назад для продолжения итерации
rs.previous();
}
}
}
Сравнение Cursor в разных БД
| БД | Тип | Поддержка |
|---|---|---|
| MySQL | JDBC ResultSet | Прокручиваемые, но требуют TYPE_SCROLL_INSENSITIVE |
| PostgreSQL | JDBC ResultSet | Полная поддержка курсоров |
| Oracle | JDBC ResultSet + Cursor | Расширенная поддержка |
| SQL Server | JDBC ResultSet | Полная поддержка прокручиваемых |
Производительность
// ❌ НЕЭФФЕКТИВНО - пересчёт для каждого доступа
for (int i = 1; i <= totalRows; i++) {
rs.absolute(i);
process(rs);
}
// ✅ ЭФФЕКТИВНО - один проход
rs.beforeFirst();
while (rs.next()) {
process(rs);
}
Важные замечания
- Cursor начинает позицию ПЕРЕД первой строкой — нужно вызвать next()
- TYPE_FORWARD_ONLY быстрее — используй, если не нужна прокрутка
- Работай с курсором в try-with-resources — для автоматического закрытия
- Проверяй hasNext() перед next() — избегай исключений
Вывод: Cursor в ResultSet — это механизм JDBC для навигации по результатам запроса. Основной метод — next(), который движет курсор на следующую строку. Для полной навигации используй TYPE_SCROLL_INSENSITIVE или TYPE_SCROLL_SENSITIVE.