Работа с RowSet

Модуль 4. Работа с БД
8 уровень , 5 лекция
Открыта

6.1 Знакомство с RowSet

Как ты уже знаешь, стандарту JDBC уже почти 20 лет, и он немного устарел. В него потихоньку добавляют новые типы и новые классы, но не везде это можно сделать красиво. И одно из таких мест — это ResultSet.

Работу с базой данных можно сделать более эффективной, но интерфейс ResultSet слабо для этого подходит. Кроме того, мы нигде явно не создаем его объекты, нам их возвращает метод executeQuery().

Создатели JDBC не стали долго думать и сделали механизм, полностью параллельный всему, что было до этого. И называться он стал RowSet.

Вот его основные преимущества:

  • RowSet расширяет интерфейс ResultSet, поэтому его функции более мощные, чем у ResultSet.
  • RowSet более гибко перемещается по данным таблицы и может прокручивать назад и вперед.
  • RowSet поддерживает кэшированные данные, которые можно использовать даже после закрытия соединения.
  • RowSet поддерживает новый метод подключения, ты можешь подключиться к базе данных без подключения. Также он поддерживает чтение источника данных XML.
  • RowSet поддерживает фильтр данных.
  • RowSet также поддерживает операции соединения таблиц.

Типы RowSet:

  • CachedRowSet
  • FilteredRowSet
  • JdbcRowSet
  • JoinRowSet
  • WebRowSet

6.2 Создание объекта RowSet

Есть три разных способа получить рабочий объект .

Во-первых, его можно заполнить данными из ResultSet, полученного классическим способом.

Например, мы можем закешировать данные ResultSet с помощью CachedRowSet:


Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
 
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
crs.populate(results);		// Используем ResultSet для заполнения

Во-вторых, можно создать полностью автономный объект RowSet, создав для него свое собственное подключение к базе данных:


JdbcRowSet rowSet = RowSetProvider.newFactory().createJdbcRowSet();
rowSet.setUrl("jdbc:mysql://localhost:3306/test");
rowSet.setUsername("root");
rowSet.setPassword("secret");
 
rowSet.setCommand("SELECT * FROM user");
rowSet.execute();

И в-третьих, можно подключить RowSet к уже существующему соединению:


 Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
JdbcRowSet rowSet = new JdbcRowSetImpl(con);
 
rowSet.setCommand("SELECT * FROM user");
rowSet.execute();

6.3 Примеры работы с RowSet

Пример первый: кэширование.

Давай напишем код, где с помощью CachedRowSet закешируем все данные и будем читать их из уже закрытого соединения:


Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
 
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
crs.populate(results);	// Используем ResultSet для заполнения
 
connection.close();		// Закрываем соединение
 
// Данные из кэша все еще доступны
while(crs.next()) {
  	System.out.println(crs.getString(1)+"\t"+ crs.getString(2)+"\t"+ crs.getString(3));
}     

Пример второй: изменение строк через RowSet:


 // Подключаемся к базе данных
 CachedRowSet crs = rsf.createCachedRowSet();
 crs.setUrl("jdbc:mysql://localhost/test");
 crs.setUsername("root");
 crs.setPassword("root");
 crs.setCommand("SELECT * FROM user");
 crs.execute();                                                                                                                     	
 
// Этот тип операции может изменить только автономный RowSet
// Сначала перемещаем указатель на пустую (новую) строку, текущая позиция запоминается
 crs.moveToInsertRow();
 crs.updateString(1, Random.nextInt());
 crs.updateString(2, "Клон" + System.currentTimeMillis());
 crs.updateString(3, "Женский");
 crs.insertRow();  // Добавляем текущую (новую) строку к остальные строкам
 crs.moveToCurrentRow(); // Возвращаем указатель на ту строку, где он был до вставки
 
 crs.beforeFirst();
 while(crs.next()) {
 	System.out.println(crs.getString(1) + "," + crs.getString(2) + "," + crs.getString(3));
}
 
// А теперь мы можем все наши изменения залить в базу
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/dbtest", "root", "root");
con.setAutoCommit(false); // Нужно для синхронизации
crs.acceptChanges(con);// Синхронизировать данные в базу данных

Если тебе интересно, как это работает, можешь ознакомиться с темой в официальной документации. Моя задача в настоящий момент — просто рассказать, что такое есть.

Комментарии (13)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
20 апреля 2025
"Моя задача в настоящий момент — просто рассказать, что такое есть." - ну когда, когда уже твоей задачей станет научить нас?
СтудентJava Уровень 109
2 февраля 2025
Немного болела голова, читая все это она разболелась еще сильней!
И. Ж. Уровень 41
30 апреля 2024
Запутанно и непонятно с переходом на строки, то сначала перемещаем на пустую новую строку, потом добавляем новую строку после заполнения текущей. Это еще понятно, но зачем возвращаем указатель на ту строку, где он был до вставки. Это такая последовательность при заполнении каждой строки?
Max Dudin Уровень 6 Expert
15 сентября 2023
Прикольно, но сложно. Вроде и хочеться углубиться и запомнить, но судя по всему в этом нет практического смысла, потому что никто этим, как говорят, уже не пользуется. Вот и вопрос не пустая ли это трата времени, которого итак не хватает, бо курс довольно сжатый...
Жасаров Рысбек Уровень 114 Expert
26 января 2024
вроде много информации, а вроде мало информации, некоторые вообще не понятно
ProPorka Уровень 30
6 июня 2023

JdbcRowSet rowSet = new JdbcRowSetImpl(con);
Так уже не работает. Буду благодарен, если объясните как грамотно работать с RowSet используя именно ConnectionPool.
Даниил Уровень 92 Expert
30 октября 2023
com.sun.rowset.JdbcRowSetImpl class is not a standard part of the Java platform and is specific to certain implementations.
рост Уровень 32
25 февраля 2023
ничего не понял но лайк
Александр Огарков Уровень 4 Expert
6 декабря 2022
не понятно откуда берутся переменные crs1.getString(1) и con.setAutoCommit(false);
Владимир Уровень 109 Expert
14 декабря 2022
полагаю очепятка, если я правильно понял должно быть crs и connection2
Max Dudin Уровень 6 Expert
15 сентября 2023
это теперь понятно... Но кто такой "rsf" из (CachedRowSet crs = rsf.createCachedRowSet();)?
Max Dudin Уровень 6 Expert
15 сентября 2023
Вспоминаю чувака из фильма " ничего не вижу, ничего не слышу"(1989 год), которому постоянно прилетало по голове газетной пачкой... бумс.. "Я ничего не вижу..!! "=() потом бумс... "О!! Я вижу.. =)), но ничего не слышу..." =( поотом бумс "Я вижу, я слышу !!! =))" (слааава богу...) "Но, кто я такой?!" (блин..) или это из другого фильма?
Кирилл Уровень 111 Expert
24 октября 2023
это RowSetFactory, в предыдущем примере она называлась не rsf, а просто factory запутывают нас)