Core Java. Лекция 8

JDBC API

Иван Пономарёв, КУРС/МФТИ

RDBMS — реляционные базы данных

  • Существуют с 1970-х годов.

  • Наиболее распространённый способ хранения информации в самых разнообразных системах.

  • Большое разнообразие зрелых, стабильных и богатых возможностями продуктов: IBM DB2, Oracle, MS SQL Server, Postgres, etc. etc.

  • Язык SQL стандартизован и слабо различается в разных системах.

  • В современных реалиях больших данных теснятся различными NoSQL системами, но пока ещё лидируют по распространённости

JDBC

  • "Java Database Connectivity"

  • Стандарт взаимодействия с реляционными СУБД

  • Назван по аналогии с ODBC (Open Database Connectivity) для языка C, разработанного Microsoft

  • Первая версия в 1996 году, текущая — 4.3 (2017-09-21)

  • Активно используется десятилетиями

Структура приложения

app

JDBC Drivers

  • Разрабатываются производителями БД или сообществами

  • У хороших БД — стабильные, высокого качества драйверы

Connection Strings aka Database URLs

В специфичной для каждого драйвера манере указывают сервер, порт, базу данных и иные параметры подключения:

jdbc:sqlserver://172.16.1.114:52836;databaseName=celesta

jdbc:postgresql://127.0.0.1:5432/celesta

jdbc:oracle:thin:192.168.110.128:1521:XE

jdbc:derby://localhost:1527/corejava;create=true

Создание Connection, Statement, получение и итерация по ResultSet

sequence

Получение данных и итерация

try (Connection conn = dataSource.getConnection();
     Statement stmt = conn.createStatement()){

  ResultSet result = stmt.executeQuery("select name from speaker");

  while (result.next()) {

      System.out.println(result.getString("name"));

  }
}

Как получить JDBC Connection

То, что написано во многих тьюториалах и учебниках, и то, что вы никогда не будете делать в реальной жизни:

String connString = "jdbc:postgresql://127.0.0.1:5432/celesta"
Connection conn = DriverManager.getConnection(connString);

JDBC Connection: особенности

  • Корневой объект, «входная точка» ко всем возможностям взаимодействия с СУБД.

  • Медленно создаётся (связь по сети с СУБД, авторизация и т. д.).

  • Захватывает ресурсы: необходимо явно закрывать после использования.

  • Имеет тенденцию «портиться» («отваливаться»).

  • Не потокобезопасный. Нужен thread confinement.

  • Выход: connection pooling.

Connection Pool

pool

Connection Pool

  • Грамотно реализовать самостоятельно — сложно

  • Предоставляет ваш фреймворк / JDBC driver

  • Есть javax.sql.DataSource, являющийся стандартным интерфейсом для Connection Pool.

DataSource connectionPool = ...
try (Connection conn = connectionPool.getConnection()) {
    ...
}

Реализации Connection Pools (DataSource)

  • Apache Commons DBCP

  • Hikari CP

  • Другие фреймворки или JDBC-драйверы (например, H2)

Методы Connection

  • управление транзакциями

    • setAutoCommit

    • commit

    • rollback

  • создание statements:

    • createStatement() — создаёт универсальный объект для передачи SQL-команд

    • prepareStatement(String sql) — создаёт параметризованный шаблон SQL команды

    • prepareCall(String sql) — cоздаёт шаблон для вызова хранимой процедуры

Разновидности Statement

iostreams

Statement и PreparedStatement

int confId = ...
try (PreparedStatement stmt =
  conn.prepareStatement(
    "select name from talk where conferenceid = ?")) {
  //устанавливаем значение параметра
  //индексация с единицы!!
  stmt.setInt(1, confId);

  ResultSet result = stmt.executeQuery();
  while (result.next()) {
      System.out.println(result.getString("name"));
  }

}

SQL Injection

  • Запомним раз и навсегда: нельзя конструировать запросы в базу на основании данных от пользователя

НЕПРАВИЛЬНО

ПРАВИЛЬНО

stmt.executeQuery(
 "SELECT * FROM users " +
 "WHERE name = '" +
 userName + "'");
PreparedStatement stmt =
 conn.prepareStatement(
  "SELECT * FROM users WHERE name = ?");
stmt.setString(1, userName);
stmt.executeQuery();

SQL Injection

sql = "SELECT * FROM users WHERE name = '" + userName + "'"

userName = "' OR '1'='1"

userName = "a';DROP TABLE users;"

//... и много другой гадости

SQL Injection

sqlinjection

Демо-пример

  • Пишем базу данных выступлений на Java-конференциях

  • Основные сущности: на конференциях выступают докладчики с докладами.

  • Бывает, что один доклад делают несколько докладчиков одновременно.

ER model

systemtables

Наш учебный пример про доклады и спикеров

objects

Реальная «слоистая» архитектура серверного приложения

layers