274.50K
Category: databasedatabase

jdbc

1.

JDBC – Java Database Connectivity
Максим Гармаш
1

2.

Введение в JDBC
JDBC используется для доступа к СУБД
из Java приложений
Информация передается из отношений
(relations) в объекты и наоборот
- СУБД для поиска/упорядочивания
- объекты для проектирования/гибкости
2

3.

Архитектура JDBC
Мы будем
Это
использовать
этот
Java классы
Java
Приложение
Postgre
Driver
PostgreSQL
Oracle
JDBC
Driver
Сеть
Oracle
MySQL
Driver
MySQL
3

4.

Архитектура JDBC
Приложение
JDBC
Driver
Java код обращается к библиотеке JDBC
JDBC загружает драйвер
Драйвер взаимодействует с СУБД
Приложение может работать с разными СУБД
используя соответствующие драйвера
В идеале: смена СУБД не приводит к
изменению кода (не всегда возможно на
практике)
4

5.

Семь Шагов
Загрузка драйвера
Указание URL
Установка соединения
Создание объекта Statement
Выполнение запроса через Statement
Обработка результата
Закрытие соединения
5

6.

Загрузка драйвера
Чтобы использовать драйвер мы должны
инстанцировать его и зарегистрировать в
driver manager'е:
Driver driver = new org.postgresql.Driver();
DriverManager.registerDriver(driver);
6

7.

Альтернативный способ
Мы также можем неявно зарегистрировать
драйвер используя такой код:
Class.forName("oracle.jdbc.driver.OracleDriver");
• Class.forName загружает указанный класс
Когда OracleDriver загружен, он автоматически
создает свой экземпляр
регистрируется в DriverManager
Также имя класса драйвера может быть
передано через параметры приложения
7

8.

Пример
// Драйвер для SomeDB1
Class.forName("ORG.img.imgSQL1.SomeDriver1");
// Драйвер для SomeDB2
Driver driver = new ORG.img.imgSQL2.SomeDriver2();
DriverManager.registerDriver(driver);
// Драйвер для oracle
Class.forName("org.postgresql.Driver");
driver1
driver2
Postgre
Зарегистрированные драйверы
8

9.

Соединение с БД
Каждая БД идентифицируется URL
По указанному URL, DriverManager ищет
драйвер способный работать с указанной
СУБД
• DriverManager пробует все
зарегистрированные драйвера пока не
найден подходящий
9

10.

Соединение с БД
Connection con = DriverManager.
getConnection("jdbc:SomeDB1");
acceptsURL("jdbc:SomeDB1")?
driver1
driver2
Postgre
Зарегистрированные драйверы
Больше информации в Driver Manager API
10

11.

Формат URL
Мы используем:
DriverManager.getConnection(URL, user, pwd);
jdbc:postgresql://localhost:5432:testdb
11

12.

Взаимодействие с БД
Мы используем Statement для
- Выборки из базы
- Обновления базы
Существует три интерфейса:
Statement, PreparedStatement, CallableStatement
Каждый из них не может быть инстанцирован
Они создаются посредством Connection
12

13.

Использование Statement
String queryStr =
"SELECT * FROM Member " +
"WHERE Lower(Name) = 'harry potter'";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(queryStr);
• Метод executeQuery возвращает объект ResultSet
представляющий собой результат выполнения
запроса.
•Будет рассмотрен далее…
13

14.

Изменения с помощью
Statement
String deleteStr =
"DELETE FROM Member " +
"WHERE Lower(Name) = 'harry potter'";
Statement stmt = con.createStatement();
int delnum = stmt.executeUpdate(deleteStr);
• executeUpdate используется для запросов типа: insert, delete,
update, create table, и т. д. (все кроме выборки select)
• executeUpdate возвращает количество затронутых строк
14

15.

Prepared Statements
Prepared Statements (Подготовленные
Запросы) используются для повторяющихся
запросов
Они разбираются (компилируются) СУБД
только один раз
Значения параметров могут быть установлены
после компиляции
Вместо значений используется символ ‘?’
Prepared Statements могут рассматриваться как
запросы с параметрами которые позже
15
заменяются реальными значениями

16.

Выборка с PreparedStatement
String queryStr =
"SELECT * FROM Items " +
"WHERE Name = ? and Cost < ?";
PreparedStatement pstmt =
con.prepareStatement(queryStr);
pstmt.setString(1, "t-shirt");
pstmt.setInt(2, 1000);
ResultSet rs = pstmt.executeQuery();
16

17.

Обновление с
PreparedStatement
String deleteStr =
“DELETE FROM Items " +
"WHERE Name = ? and Cost > ?";
PreparedStatement pstmt =
con.prepareStatement(deleteStr);
pstmt.setString(1, "t-shirt");
pstmt.setInt(2, 1000);
int delnum = pstmt.executeUpdate();
17

18.

Statements vs.
PreparedStatements
Одинаковый ли этот код? Что он делает?
String val = "abc";
PreparedStatement pstmt =
con.prepareStatement("select * from R where A=?");
pstmt.setString(1, val);
ResultSet rs = pstmt.executeQuery();
String val = "abc";
Statement stmt = con.createStatement( );
ResultSet rs =
stmt.executeQuery("select * from R where A=" + val);
18

19.

Statements vs.
PreparedStatements
Будет ли это работать?
PreparedStatement pstmt =
con.prepareStatement("select * from ?");
pstmt.setString(1, myFavoriteTableString);
Нет!!! Символ ‘?’ может быть
использован как значение ячейки
19

20.

Таймаут
Используйте метод setQueryTimeOut(int
seconds) класса Statement чтобы
установить время ожидания драйвером
завершения операции
Если операция не завершена за
указанное время выбрасывается
исключение SQLException
Для чего это используется?
20

21.

ResultSet
• ResultSet обеспечивает доступ таблицам
сгенерированным в результате выполнения
запросов объектом класса Statement
Только один экземпляр ResultSet на каждый
экземпляр Statement может быть открыт
единовременно!
Данные извлекаются в следующей
последовательности:
ResultSet содержит курсор указывающий на текущую
запись
Метод next() смещает курсор на следующую запись21

22.

Методы ResultSet
• boolean next()
делает следующую запись активной
первый вызов next() активирует первую запись
возвращает false если больше нет записей
• void close()
уничтожает экземпляр ResultSet
позволят снова использовать экземпляр
Statement которым был порожден
автоматически вызывается большинством
методов Statement
22

23.

Методы ResultSet
• Type getType(int columnIndex)
возвращает значение указанного поля с типом
Type
индексация идет с 1 а не с 0!
• Type getType(String columnName)
то же, только используется имя столбца
менее эффективно
Пример: getString(columnIndex), getInt(columnName),
getTime, getBoolean, getType,...
• int findColumn(String columnName)
возвращает индекс по имени столбца
23

24.

Пример с ResultSet
Statement stmt = con.createStatement();
ResultSet rs = stmt.
executeQuery("select name,age from Employees");
// Print the result
while(rs.next()) {
System.out.print(rs.getString(1) + ":");
System.out.println(rs.getShort("age"));
}
24

25.

Соответствие типов
SQL type
CHAR, VARCHAR, LONGVARCHAR
NUMERIC, DECIMAL
BIT
TINYINT
SMALLINT
INTEGER
BIGINT
REAL
FLOAT, DOUBLE
BINARY, VARBINARY, LONGVARBINARY
DATE
TIME
TIMESTAMP
Java Type
String
java.math.BigDecimal
boolean
byte
short
int
long
float
double
byte[]
java.sql.Date
java.sql.Time
java.sql.Timestamp
25

26.

Null значения
В SQL, NULL что поле пустое
Не одно и тоже, что 0 или ""
В JDBC, нужно явно проверять является
ли считаное значение null
- ResultSet.wasNull(column)
Пример: getInt(column) возвратит 0 в обоих
случаях 0 и NULL!
26

27.

Null значения
При вставке null-значений в с помощью
Prepared Statements:
Используйте метод setNull(index, Types.sqlType)
для примитивных типов (INTEGER, REAL);
Также можно использовать setType(index, null)
для object-типов (STRING, DATE).
27

28.

Мета-данные ResultSet
ResultSetMetaData - это объект который
используется для получения информации о
свойствах полей объекта ResultSet
Пример: вывести имена колонок
ResultSetMetaData rsmd = rs.getMetaData();
int numcols = rsmd.getColumnCount();
for (int i = 1 ; i <= numcols; i++) {
System.out.print(rsmd.getColumnLabel(i)+" ");
}
28

29.

Тип данных Время
Время в SQL самый нестандартный тип
В Java существуют три класса для работы с
ним
• java.sql.Date
год, месяц, день
• java.sql.Time
часы, минуты, секунды
• java.sql.Timestamp
год, месяц, день, часы, минуты, секунды,
наносекунды
обычно используют этот
29

30.

Подчищаем за собой :)
Помните о необходимости закрытия
объектов Connection, Statement, Prepared
Statement и ResultSet
con.close();
stmt.close();
pstmt.close();
rs.close()
30

31.

Работа с исключениями
SQLException – обычно содержит много
дополнительной информации
catch (SQLException e) {
while (e != null) {
System.out.println(e.getSQLState());
System.out.println(e.getMessage());
System.out.println(e.getErrorCode());
e = e.getNextException();
}
}
31

32.

Работа с транзакциями
32

33.

Транзакции в JDBC
Транзакция: одно или более выражений SQL
которые должны звершиться успешно (или не
успешно) вместе
Например: обновление нескольких таблиц при
осуществлении покупки
Если одно из действий завершится неудачно,
нужно отменить все предшествующие действия
Таже нельзя оставлять БД в нецелостном
состоянии во время транзакции
• COMMIT = подтвердить транзакцию
• ROLLBACK = отменить все действия
33

34.

Пример
Допустим мы хотим перевести деньги в банке
со счета 13 на счет 72:
PreparedStatement pstmt =
con.prepareStatement("update BankAccount
set amount = amount + ?
where accountId = ?");
pstmt.setInt(1,-100);
pstmt.setInt(2, 13);
Что произойдет, если
pstmt.executeUpdate();
этот update не
pstmt.setInt(1, 100);
выполнится?
pstmt.setInt(2, 72);
pstmt.executeUpdate();
34

35.

Управление Транзакциями
Транзакции явно не открываются и не
закрываются
У соединения есть особый режим называемый
AutoCommit
Если свойство AutoCommit установлено в true, то
каждая команда будет автоматически
зафиксирована
Если AutoCommit установлено в false, то каждая
команда добавляется в текущую транзакцию
По умолчанию: true
35

36.

AutoCommit
setAutoCommit(boolean val)
Если AutoCommit установлено в false, нужно явно
фиксировать или откатывать транзакцию при помощи
Connection.commit() и Connection.rollback()
Замечание: DDL запросы (пр., создание/удаление
таблиц) в транзакции может быть проигнорированно
или вызвать фиксацию
Поведение зависит от конкретной СУБД
36
English     Русский Rules