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);// Синхронізувати дані до бази даних

Якщо тобі цікаво, як це працює, можеш ознайомитись із темою в офіційній документації. Моє завдання зараз просто розповісти, що таке є.