JDBC Flashcards
driver jar контент
Каждый driver jar содержит имплементации для пяти основных интерфейсов:
1) CallableStatement -знает как выполнять хранимый sql запрос
2) PreparedStatement- знает как выполнять sql запрос
3) Driver- знает как установить соединение с БД
4) Connection- знает как общаться с БД(отправлять в нее команды)
5) ResultSet -знает как оперировать с результатом возвращенным БД
Сами интерфейсы находятся в java.sql
!!!Все методы этих интерфейсов бросают SQLException
Выполнение SQL запроса через JDBC
Все имплементации интерфейсов Connection, ResultSet,PreparedStatement реализуют closeable и должны быть закрыты
1) Получаем Connection через DriverManager.getConnection(url) или перегруженный getConnection(url, username,password) - он по урлу среди всех драйверов на класспасе ищет подходящий
- если драйвер не будет найден для данного урла то будет SQLException
!!!Раньше для подгрузки класса с драйвером необходимо было подгружать класс с помощью Class.forName(“sql.MysqlDriver”)-теперь это не обязательно т.к. С JDBC 4/0 и с 6 джавы все драйвера содержат вышеуказанный файл.
2) var statement = connection.prepareStatement(“SELECT * FROM users”)
3)int rowsAffected = statement.executeUpdate() для INSERT,UPDATE,DELETE
или ResultSet rs = statement.executeQUery() для SELECT
или boolean execute() для всех типов запросов
JDBC connection url
jdbc:vendorname(mysql or postgresql):{db connection details e.g. adress and dm name - //localhost:8080/animals}?param=value
Если используется // то может быть localhost IP или доменное имя
ResultSet
В начале курсор находится перед первым рядом. Чтобы начать получать данные нужно перемещать курсор методом boolean next(), который перемещает курсор на один ряд и возвращает true если ряд имеется иначе false.
Если ряд имеется то можно достать из ряда данные методами getString/Int/Double/Long/Boolean/Object (“columnname” or columnNumber (стартует с 1)- по имени предпочтительнее). Если вызвать эти методы когда курсор не указывает на ряд то будет SQLException
PreparedStatement методы выполнения
1) int executeUpdate() выполняет запрос INSERT,UPDATE,DELETE (при другом запросе кидает SQLException) и возвращает количество измененных рядов
2) ResultSet executeQUery() выполняет SELECT (при другом запросе кидает SQLException)
3) boolean execute() - выполняет любой запрос и возвращает true если можно извлечь resultSet методом getResultSet()- иначе можно достать количество измененных рядов методом getUpdateCount()
4) addBatch() сохраняет данный запрос и создает новую порцию батча.
5) int[] executeBatch()- выполняет массово INSERT,UPDATE,DELETE запросы добавленные методом addBatch()- возврашает массив количеств измененных рядов для каждого отдельного запроса в батче
6) ResultSet executeQuery(String sql), int executeUpdate(String sql), boolean execute(String sql) -есть перегруженные версии унаслоедованные от Statement- они не производят подготовки и вставки плэйсхолдеров- поэтому при передаче в них SQL с плэйсхолдерами будет SQLException
PreparedStatement создание
При создании можно передавать запрос с плэйсхолдерами ‘?’
Плэйсхолдеры заполняются методами PreparedStatement setString/Int/Double/Long/Boolean/Object (int number of placeholder, value) и т.д.
Если не все плэйсхолдеры будут заполнены, или будут заполнены несуществующие, то будет SqlException.
Также можно переиспользовать уже выполненный PreparedStatement. Все значения вставленные в него сохраняются, но их можно перезаписать и выполнить повторно.
CallableStatement
Создается методом conn.prepareCall(sql)
SQL имеет синтакс
{call func_name()} -без параметров возвращающий ResultSet
{call func_name(?)}- с параметром возвращает ResultSet
{?= call func_name(?) } - без параметра возвращает значение- ?= опциональный элемент
{?= call func_name(?) } - с параметром возвращает значение- ?= опциональный элемент
Для вставки параметра нужно вызвать соответствующий метод setInt/Long/String/Double/Object при этом в отличие от PreparedStatement первый аргумент может быть не только номером аргумента с 1 но и его именем.
Любой output аргумент нужно зарегистрировать методом registerOutputArgument(int номер аргумента или String его имя, SQLType)
Выполнять запросы возвращающие ResultSet нужно через executeQuery- остальные через execute
При этом для запросов которые выполняем через execute, OUT аргументы нужно получать вызовом getINt/Long/Double/String/Object(int argNumber or String argName) у самого CallableStatement
SQLException доп. методы
1) getSQLState()-возращает ошибку БД
2) getErrorCode()-возвращает БД специфичный код ошибки
Закрытие JDBC ресурсов
Должны закрываться следующие ресурсы- Connection, Statement, ResultSet
При этом если мы сами их закрываем то закрывать их нужно в таком порядке ResultSet > Statement > Connection
Но так как они взаимозависимы то при закрытии COnnection закрывается и ResultSet и Statement, при закрытии Statement закрывается ResultSet.
Также етсь нюанс, что при повторном выполнении PreparedStatement прошлый ResultSet автоматом закрывается.