1. Повний список типів даних JDBC

Окрім відомих тобі типів даних, JDBC дозволяє працювати з багатьма рідними типами даних для СУБД. Нижче я наведу список типів та функції для їх отримання:

Тип Метод
Array getArray()
AsciiStream getAsciiStream()
BigDecimal getBigDecimal()
BinaryStream getBinaryStream()
Blob getBlob()
Boolean getBoolean()
Blob getBlob()
Boolean getBoolean()
Byte getByte()
Bytes getBytes()
CharacterStream getCharacterStream()
Clob getClob()
Date getDate()
Double getDouble()
Float getFloat()
Int getInt()
Long getLong()
NCharacterStream getNCharacterStream()
Object getObject()
Ref getRef()
RowId getRowId()
Short getShort()
SQLXML getSQLXML()
String getString()
Time getTime()
Timestamp getTimestamp()
UnicodeStream getUnicodeStream()
URL getURL()

Примітивні типи ми з тобою вже розглядали. Давай спробуємо попрацювати з об'єктами.

2. Тип даних BLOB

Якщо ти хочеш зберегти якийсь об'єкт у базу даних, то найпростіший спосіб зробити це — скористатись SQL-типом BLOB. JDBC має його аналог, який називається Blob.

BLOB розшифровується як Binary Large Object. Він використовується для зберігання масиву байт. Тип Blob у JDBC є інтерфейсом? і в нього можна класти (і отримувати з нього) дані двома способами:

  • За допомогою InputStream
  • За допомогою масиву байт

Приклад: колонка номер 3 містить тип BLOB:


Statement statement = connection.createStatement();
    ResultSet results = statement.executeQuery("SELECT * FROM user");
    results.first();
 
    Blob = results.getBlob(3);
    InputStream is = blob.getBinaryStream();

Щоб створити свій об'єкт Blob, потрібно скористатися функцією createBlob(). Приклад:


  String insertQuery = "INSERT INTO images(name, image) VALUES (?, ?)";
  PreparedStatement statement = connection.prepareStatement(insertQuery);
 
  // Створюємо об'єкт Blob і отримуємо в нього OutputStream для запису даних
  Blob blob = connection.createBlob();
 
  // Заповнюємо Blob даними …
  OutputStream os = blob.setBinaryStream(1);
 
  // Передаємо Вlob як параметр запиту
  statement.setBlob(2, blob);
  statement.execute();

Заповнити Blob даними можна двома способами. Перший — через OutputSteam:


  Path avatar = Paths.get("E:\images\cat.jpg");
  OutputStream os = blob.setBinaryStream(1);
  Files.copy(avatar, os);

І другий — через заповнення байтами:


  Path avatar = Paths.get("E:\images\cat.jpg");
  byte[] content = Files.readAllBytes(avatar);
  blob.setBytes(1, content);

3. Зберігаємо Java-об'єкт до бази

Ми навчилися зберігати до бази бінарні об'єкти: масиви байт, байтові потоки тощо. А як щодо Java-об'єктів? Як зберегти Java-об'єкт у базі даних?

Припустимо, у нас є Java-клас Employee, який описує співробітника компанії:


public class Employee {
    public Integer id;
    public String name;
    public String occupation;
    public Integer salary;
    public Date joinDate;
}

Як нам зберегти об'єкт цього класу в базі за допомогою JDBC?

Насправді, ти вже знаєш усе, що для цього потрібно. Спочатку потрібно створити таблицю в базі, яка відповідає цьому класу. Наприклад, таку:


CREATE TABLE employee {
    id INT PRIMARY KEY NOT NULL,
    name VARCHAR(100),
    occupation VARCHAR(100),
    salary INT,
    join_date DATE
}

А тепер напишемо код, який додасть об'єкт нашого класу Employee до бази:


public static boolean addEmployee(Connection connection, Employee employee) throws Exception {
    // Створюємо та готуємо запит на вставлення даних до таблиці
    String insertQuery = "INSERT INTO employee(name, occupation, salary, join_date ) VALUES (?, ?, ?, ?)";
    PreparedStatement statement = connection.prepareStatement(insertQuery);
 
    // Заповнюємо запит даними з об'єкта Employee
    statement.setString(1, employee.name);
    statement.setString(2, employee.occupation);
    statement.setInt(3, employee.salary);
    statement.setDate(4, employee.joinDate);
 
    // Виконуємо наш запит, і він повертає true, якщо новий рядок додався
    int count = statement.executeUpdate();
    return count > 0;
    }

Просто та зрозуміло. Метод буде добре працювати.

4. Читаємо Java-об'єкт з бази

Записувати об'єкт у базу ми навчилися, тепер давай напишемо код, щоб читати об'єкт із бази. Почнемо з коду, який читає об'єкт із бази за його ID:


public static Employee getEmployeeById(Connection connection, int id) throws Exception {
    // Створюємо та готуємо запит для отримання співробітника з таблиці
    PreparedStatement statement = connection.prepareStatement("SELECT * FROM employee WHERE id = ?");
    statement.setInt(1, id);
    
    // Виконуємо наш запит, і він повертає null, якщо рядків у результаті запиту немає
    ResultSet results = statement.executeQuery();
    if (!results.first())
        return null;
 
    // Заповнюємо об'єкт Employee даними з ResultSet
    Employee employee = New Employee();
    employee.id = results.getInt(1);
    employee.name = results.getString(2);
    employee.occupation = results.getString(3);
    employee.salary = results.getInt(4);
    employee.joinDate = results.getDate(5);
    return employee;
}

А якщо нам потрібний не один об'єкт, а кілька? Такий запит також написати просто. Давай отримаємо всіх співробітників нашої компанії:


    public static List<Employee> getAllEmployees(Connection connection) throws Exception {
    // Створюємо та виконуємо запит для отримання співробітників з таблиці
    Statement statement = connection.createStatement();
    ResultSet results = statement.executeQuery("SELECT * FROM employee");
 
    ArrayList<Employee> list = new ArrayList<Employee>();
    while (results.next()) {
            // Заповнюємо об'єкт Employee даними з поточного рядка ResultSet
Employee employee = New Employee();
employee.id = results.getInt(1);
employee.name = results.getString(2);
employee.occupation = results.getString(3);
employee.salary = results.getInt(4);
employee.joinDate = results.getDate(5);
 
list.add(employee);
    }
    return list;
    }

До речі, якщо таких методів буде багато, то в кожному з них доведеться писати однаковий код з перетворення рядка ResultSet на об'єкт Employee. Отже, цей код можна винести в окремий метод.

Це може бути корисно, якщо клас Employee містить складні поля типу Enum, InputStream, або посилання на інші об'єкти, які ми хочемо зберігати в базі.