Модуль 3 Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок.

Презентация:



Advertisements
Похожие презентации
Модуль 5 Рассматриваемые темы: Метаданные Групповая модификация данных Вопросы типизации Дополнительные возможности JDBC API слайд 5-1.
Advertisements

Модуль 4 Рассматриваемые темы: Понятие транзакции Конкурентный доступ к данным Использование транзакций в JDBC API Транзакции в JDBC API слайд 4-1.
Разработка телекоммуникационной и информационной системы для прогнозирования аварий и катастроф на НПЗ.
PL/SQL Курсоры. Курсор – специальный элемент, связанный с SQL-оператором SELECT. Объявление курсора происходит в секции объявления базового блока. Работа.
Java : доступ к базам данных, технология JDBC. Примеры баз данных.
ОРГАНИЗАЦИЯ БАЗ ДАННЫХ И ЗНАНИЙ ТЕМА 5 СТРУКТУРИРОВАННЫЙ ЯЗЫК ЗАПРОСОВ SQL.
Основы SQL Запросы к базе данных. Что такое база данных SQL? SQL (Structured Query Language - «Структурированный язык запросов») - универсальный компьютерный.
Triggers для mysql. Что есть триггер? Триггер - это хранимая процедура особого типа, исполнение которой обусловлено наступлением определенного события.
Тамбовский государственный университет имени Г.Р. Державина Институт математики, физики и информатики Кафедра информатики и информационных технологий Иванова.
Выполнение запросов, создание и редактирование отчета MS Access.
Программирование с БД Клиент-серверная архитектура API JDBC.
СУБД Access Запросы Автор: Тутыгин В.С.. Назначение запросов Запросы обеспечивают простой доступ к определенному подмножеству записей одной или нескольких.
условия Пакеты java.sql и javax.sql содержат классы и интерфейсы для работы с БД Для подключения к конкретной.
«ИЗМЕНЕНИЕ ДАННЫХ В БД» Выполнил: студент 722 группы Специальности Информационные системы (по отрослям) Токарев Виктор.
Java Database Connectivity (JDBC) Универсальное API для доступа к данным.
Урок 3. Формы представления данных (таблицы, формы, запросы, отчеты)
Работа с файлами Сазонов Д.О. ПМиЭММ Часть 2. Тема занятия: Работа с файлами через потоки Для реализации файлового ввода/вывода, необходимо включить в.
Администрирование информационных систем Администрирование БД. Управление разрешениями.
Семантический анализ КC-грамматики, с помощью которых описывают синтаксис языков программирования, не позволяют задавать контекстные условия (КУ), имеющиеся.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Транксрипт:

Модуль 3 Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок Взаимодействие с СУБД посредством JDBC API слайд 3-1

SQL-запросы к СУБД Соединение с СУБД Создание запросов (SQL Statements) Управление транзакциями Получение информации о схеме базы данных В данном блоке мы сконцентрируемся на создании запросов Интерфейс Connection слайд 3-2

SQL-запросы к СУБД SQL-statement – это Java-объект, репрезентующий данный SQL-запрос в хипе JVM приложения-клиента Запросы «вытягиваются» из соединения ( Connection ) Запросы реализуют интерфейс Statement из JDBC API Запрос – это экземпляр какого класса? Запросы (SQL-statements) слайд 3-3

SQL-запросы к СУБД Запрос – это экземпляр класса, который является частью JDBC- драйвера Разработчик класса запроса – разработчик JDBC-драйвера Разработчику приложения-клиента СУБД не всегда важно, какие классы образуют драйвер Запросы (SQL-statements) слайд 3-4

SQL-запросы к СУБД Запросы используются для: Выборки данных ( select ) Модификации данных ( insert, update, delete ) В JDBC API предусмотрены специализированные интерфейсы для запросов различного характера Типы запросов слайд 3-5

SQL-запросы к СУБД Типы интерфейсов запросов, их наследование слайд 3-6 Интерфейс Statement (используется для выполнения обычных SQL-запросов) Интерфейс PreparedStatement (используется для выполнения подготовленных запросов с или без входных параметров) Интерфейс CallableStatement (используется для вызовов хранимых процедур)

SQL-запросы к СУБД Для создания обычного запроса используется интерфейс Statement Обычный запрос – это неподготовленный запрос без входных и выходных параметров и без вызова хранимых процедур Обычный запрос слайд 3-7

SQL-запросы к СУБД Типы интерфейсов запросов, их наследование слайд 3-8 Интерфейс Statement (используется для выполнения простых SQL- запросов без параметров) Интерфейс PreparedStatement (используется для выполнения подготовленных запросов с или без входных параметров) Интерфейс CallableStatement (используется для вызовов хранимых процедур)

SQL-запросы к СУБД Современные СУБД выполняют SQL- запросы в несколько этапов: Анализ Компиляция Проверка прав Оптимизация Собственно, выполнение Для одинаковых запросов накладно повторять начальные этапы Подготовленные запросы слайд 3-9

SQL-запросы к СУБД Подготовленный запрос – это SQL- запрос, который перед непосредственно выполнением подготавливается, т.е. выполняются начальные этапы Результаты выполнения начальных этапов сохраняются, и при следующих вызовах они не выполняются, это экономит время Подготовленные запросы слайд 3-10

SQL-запросы к СУБД Типы интерфейсов запросов, их наследование слайд 3-11 Интерфейс Statement (используется для выполнения простых SQL- запросов без параметров) Интерфейс PreparedStatement (используется для выполнения подготовленных запросов с или без входных параметров) Интерфейс CallableStatement (используется для вызовов хранимых процедур)

SQL-запросы к СУБД Хранимая процедура – бизнес-логика, реализованная на стороне СУБД Язык программирования специфичен для СУБД Хранимые процедуры могут принимать входные (IN) и выходные (OUT) параметры Хранимые процедуры могут возвращать результат Вызов хранимых процедур слайд 3-12

SQL-запросы к СУБД Выводы по типам запросов слайд 3-13 Интерфейс Statement (используется для выполнения простых SQL- запросов без параметров) Интерфейс PreparedStatement (используется для выполнения подготовленных запросов с или без входных параметров) Интерфейс CallableStatement (используется для вызовов хранимых процедур)

SQL-запросы к СУБД Создание обычного запроса: Создание запросов слайд 3-14 Connection connection = DriverManager.getConnection(DBURL); Statement statement = connection.createStatement(); MyDBClient.java Connection connection = DriverManager.getConnection(DBURL); PreparedStatement statement = connection.prepareStatement(SQLQuery); MyDBClient.java Создание подготовленного запроса: Создание запроса-вызова хранимой процедуры: Connection connection = DriverManager.getConnection(DBURL); CallableStatement statement = connection.prepareCall(SQLQuery); MyDBClient.java

SQL-запросы к СУБД Почему мы не задаем SQL-строку при создании объекта обычного запроса? Почему при создании объекта подготовленного запроса мы её задаем? слайд 3-15 Создание запросов

SQL-запросы к СУБД При создании объекта обычного запроса мы не указываем SQL- строку, т.к. мы будем каждый раз задавать её при выполнении запроса При создании объекта подготовленного запроса мы задаем SQL-строку, а затем при каждом вызове будем только определять значения параметров слайд 3-16 Создание запросов – выводы

SQL-запросы к СУБД Методы выполнения SQL-запросов: Интерфейс Statement слайд 3-17 ResultSet executeQuery(String SQL) int executeUpdate(String SQL) boolean execute(String SQL) boolean getMoreResults() ResultSet getResultSet() int getUpdateCount() Методы интерфейса Statement

SQL-запросы к СУБД Выборка (курсор) – Java- представление результата выполнения select- оператора, набор записей В JDBC API выборки представлены интерфейсом ResultSet Более подробно выборки рассматриваются в следующем блоке Введение в выборки (курсоры) слайд 3-18

SQL-запросы к СУБД Метод executeQuery необходим для запросов, результатом которых является одна выборка: Выполнение запросов – executeQuery слайд 3-19 Connection connection = DriverManager.getConnection(DBURL); Statement statement = connection.createStatement(); ResultSet result = statement.executeQuery(SELECT * FROM employee); while(result.next()) { String userName = result.getString(1); String password = result.getString(name); } MyDBClient.java

SQL-запросы к СУБД Метод executeUpdate возвращает целое число ( int ), показывающее, сколько записей было затронуто запросом Используется для выполнения операторов DML INSERT, UPDATE или DELETE, а также для операторов DDL, например CREATE TABLE Для выражений DDL результат всегда нулевой Выполнение запросов – executeUpdate слайд 3-20

SQL-запросы к СУБД Выполнение запросов – executeUpdate слайд 3-21 Connection connection = DriverManager.getConnection(DBURL); Statement statement = connection.createStatement(); int result = statement.executeUpdate(DELETE FROM employee); MyDBClient.java

SQL-запросы к СУБД Используется, когда операторы SQL возвращают более одной выборки, более одного счетчика обновлений или и то, и другое Такие множественные результаты, хоть и редки, но возможны при вызове некоторых хранимых процедур или вызове неизвестного на этапе компиляции SQL-запроса Выполнение запросов – execute слайд 3-22

SQL-запросы к СУБД Этот метод возвращает true, если команда возвратила выборку, и false в противном случае Tсли возвращается true, то приложение получает выборку вызовом метода getResultSet() у запроса Метод getUpdateCount() запроса служит для подсчета числа строк, модифицированных командой Для получения следующего результата служит метод getMoreResults() запроса Выполнение запросов – execute слайд 3-23

SQL-запросы к СУБД Выполнение запросов – execute слайд 3-24 Connection connection = DriverManager.getConnection(DBURL); Statement statement = connection.createStatement(); boolean result = statement.execute(SQL_FROM_USER); if( result ) { ResultSet resultset = statement.getResultSet(); while( resultset.next() ) { //Работаем с выборкой } } else { System.out.println(statement.getUpdateCount() + " строк обработано."); } statement.close(); connection.close(); MyDBClient.java

SQL-запросы к СУБД Разработчику следует явно закрывать запросы по тем же причинам, что и соединения Спецификация JDBC регламентирует, что при закрытии соединения должны закрываться все связанные с ним объекты (запросы, выборки) Но это зависит от реализации драйвера Поэтому хорошей практикой является явное последовательное закрытие выборок, запросов, соединений Закрытие объекта запроса слайд 3-25

SQL-запросы к СУБД Выводы по простым запросам слайд 3-26 Connection connection = DriverManager.getConnection(DBURL); Statement statement = connection.createStatement(); ResultSet executeQueryResult = statement.executeQuery(SELECT * FROM employee); //Работа с выборкой – цикл по ResultSet boolean executeResult = statement.execute( SQL_FROM_USER ); //Работа с комплексным результатом – цикл по набору результатов int updateResult = statement.executeUpdate(DELETE FROM employee); //Работа с результатом обновления executeQueryResult.close(); statement.close(); connection.close(); MyDBClient.java

SQL-запросы к СУБД Современные СУБД выполняют SQL- запросы в несколько этапов: Анализ Компиляция Проверка прав Оптимизация Собственно, выполнение Для одинаковых запросов накладно повторять начальные этапы Подготовленные запросы слайд 3-27

SQL-запросы к СУБД Подготовленный запрос – это SQL- запрос, который перед непосредственно выполнением подготавливается, т.е. выполняются начальные этапы Результаты выполнения начальных этапов сохраняются, и при следующих вызовах они не выполняются, это экономит время Подготовленные запросы слайд 3-28

SQL-запросы к СУБД Подготовленный запрос может принимать входные (IN) параметры Можно неоднократно вызывать подготовленный запрос с различными значениями параметра, и это не приведет к переподготовке запроса Параметры в подготовленных запросах слайд 3-29 SELECT * FROM employees WHERE salary > ? AND salary < ? SQL-запрос с двумя входными параметрами

SQL-запросы к СУБД При создании объекта запроса разработчик указывает SQL-строку В этот момент происходит подготовка, довольно затратный процесс для сложных запросов Подготовка запроса слайд 3-30 PreparedStatement preparedStatement = connection.prepareStatement(UPDATE employees SET name=? WHERE id=?); MyDBClient.java

SQL-запросы к СУБД После подготовки запроса необходимо установить значения параметров Для этого необходимо указать номер и тип параметра Установка параметров слайд 3-31 PreparedStatement preparedStatement = connection.prepareStatement(UPDATE employees SET name=? WHERE id=?); preparedStatement.setString(1, putin v. v.); preparedStatement.setInt( 2, 1000);

SQL-запросы к СУБД Как отобразить Java-тип данных на SQL- тип при установке параметра? Особенно, с учетом того, что многие СУБД имею нестандартные типы? Спецификация JDBC регламентирует отображение Java-типов на стандартные SQL-типы Для не-SQL типов следует обратиться к документации производителя драйвера Типизация параметров слайд 3-32

SQL-запросы к СУБД слайд 3-33 //Подготовка запроса PreparedStatement preparedStatement = connection.prepareStatement(UPDATE employees SET name=? WHERE id=?); // Установка параметров запроса preparedStatement.setString(1, putin v. v. ); preparedStatement.setInt(2, 1000 ); // Выполнение запроса int updateResult = preparedStatement.executeUpdate(); MyDBClient.java Выводы по работе с подготовленными запросами

SQL-запросы к СУБД слайд 3-34 Вопросы по целесообразности подготовленных запросов При каких схемах доступа клиента к СУБД использование подготовленных запросов будет максимально эффективно? см. далее

SQL-запросы к СУБД слайд 3-35 Веб-пользователи СУБД Клиентское ПО (веб-браузер) Промежуточное ПО доступа к СУБД (DB middleware) БД-пользователи Клиентское ПО (клиент СУБД) Сервер приложений (веб)

SQL-запросы к СУБД Хранимая процедура – бизнес-логика, реализованная на стороне СУБД Язык программирования специфичен для СУБД Хранимые процедуры могут принимать входные (IN), выходные (OUT) и INOUT-параметры Хранимые процедуры могут возвращать результат Вызов хранимых процедур слайд 3-36

SQL-запросы к СУБД Стандартный формат вызова хранимых процедур (используется как в ODBC, так и в JDBC) { call sp_A } { ? = call sp_B( ? ) } { call sp_C( ?, ?, ? ) } Вызов хранимых процедур слайд 3-37

SQL-запросы к СУБД Для вызова хранимой процедуры следует использовать интерфейс CallableStatement У него присутствует дополнительный метод для регистрации OUT-параметров Далее следует активировать вызов методом execute() Снять значение out-параметра после вызова процедуры можно методом get XXX () интерфейса CallableStatement Вызов хранимых процедур слайд 3-38 void registerOutParameter(int parameterIndex, int sqlType)

SQL-запросы к СУБД Пример вызова хранимых процедур слайд 3-39 //Подготовка вызова CallableStatement callableStatement = connection.prepareCall(call sp_A(?, ?)); //Установка параметров callableStatement.setInt(1, 200); callableStatement.registerOutParameter(2, Types.STRING); //Вызов callableStatement.execute(); //Снятие значения out-параметра String s = callableStatement.getString(2); MyDBClient.java

SQL-запросы к СУБД Анализ результатов вызова производится, как было разобрано в предыдущем блоке, при обсуждении метода execute() Вызов хранимых процедур слайд 3-40

SQL-запросы к СУБД Выводы по вызову хранимых процедур слайд 3-41 //Подготовка вызова CallableStatement callableStatement = connection.prepareCall(call sp_A(?, ?)); //Установка параметров callableStatement.setInt(1, 200); callableStatement.registerOutParameter(2, Types.STRING); //Вызов callableStatement.execute(); //Снятие значения out-параметра String s = callableStatement.getString(2); MyDBClient.java

Взаимодействие с СУБД Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок слайд 3-42

SQL-запросы к СУБД Выборка (курсор) – Java- представление результата выполнения select- оператора, набор записей В JDBC API выборки представлены интерфейсом ResultSet Выборки (курсоры) слайд 3-43

SQL-запросы к СУБД Доступ к записям выборки Доступ к полям записей Навигация по набору данных Модификация данных Модифицируемые курсоры Предоставление метаинформации о выборке Интерфейс ResultSet слайд 3-44

SQL-запросы к СУБД Выборка содержит набор записей, одна из которых является активной (или текущей) Вызов метода next() интерфейса ResultSet приводит к активизации следующей записи в выборке Метод next() возвращает boolean- переменную, которая показывает, не достигнута ли последняя запись выборки Объект выборки слайд 3-45

SQL-запросы к СУБД Изначально курсор спозиционирован перед первой записью, и первый вызов next() перемещает его на первую строку Выборка сохраняется до тех пор, пока не закроется её объект или его родительский Statement Объект выборки слайд 3-46

SQL-запросы к СУБД Перемещение по выборке слайд 3-47 Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM emplyee"); while( resultSet.next() ) { //Анализ полей текущей (активной) записи } MyDBClient.java Не все СУБД поддерживают произвольное (не только вперед) перемещение по выборке Это называется выборка с произвольным доступом

SQL-запросы к СУБД В выборке существует одна текущая (или активная) запись, метод next() делает текущей следующую запись Разработчик может получить доступ к полям текущей записи Для этого следует знать: Имя или номер нужного поля Тип нужного поля Анализ полей записи слайд 3-48

SQL-запросы к СУБД Интерфейс ResultSet предоставляет набор getter-методов для снятия значения выбранного поля текущей записи: Type get Type (int) Type get Type (String) Здесь важно внимательно отнестись к отображению SQL-типов данных на Java-типы Анализ полей записи слайд 3-49

SQL-запросы к СУБД Пример анализа полей записи слайд 3-50 Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM emplyee"); while( resultSet.next() ) { int i = resultSet.getInt( age ); String s = resultSet.getString( 2 ); float f = resultSet.getFloat( salary ); System.out.println("ROW = " + i + " " + s + " " + f); } MyDBClient.java

SQL-запросы к СУБД NULL-значение – это отсутствие данных в поле При снятии значения поля, в котором было NULL-значение, методы get XXX () вернут нулевое значение данного типа: Для примитивных типов это их значения по умолчанию Для объектных типов это null Это может привести к неправильной интерпретации результата NULL-значения слайд 3-51

SQL-запросы к СУБД Следует воспользоваться методом ResultSet.wasNull() после анализа каждого поля NULL-значения слайд 3-52

SQL-запросы к СУБД Пример анализа полей записи слайд 3-53 Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM emplyee"); while( resultSet.next() ) { int i = resultSet.getInt( age ); if( resultSet.wasNull() ) i = -1; //Иначе i=0 String s = resultSet.getString( 2 ); if( resultSet.wasNull() ) s = ; //Иначе s=null float f = resultSet.getFloat( salary ); if( resultSet.wasNull() ) f = -1; // Иначе f=0 System.out.println("ROW = " + i + " " + s + " " + f); } MyDBClient.java

SQL-запросы к СУБД слайд 3-54 Выводы по использованию выборок Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM emplyee"); while( resultSet.next() ) { int i = resultSet.getInt( age ); String s = resultSet.getString( 2 ); float f = resultSet.getFloat( salary ); System.out.println("ROW = " + i + " " + s + " " + f); } MyDBClient.java

SQL-запросы к СУБД Где реально располагается набор данных – на сервере БД или на клиентской JVM? слайд 3-55 Вопросы по устройству выборок см. далее

слайд 3-56 Серверный курсор Интерфейс ResultSet Объект, реализующий выборку ResultSet rs.next() JVM Сервер БД next() на языке СУБД API Запись Серверный курсор rs = stmt.executeQuery() execute() на языке СУБД API 2 2 Создание выборки (как?) 3 3 см. далее SQL-запросы к СУБД

слайд 3-57 Клиентский курсор rs.next() Сервер БД Серверный курсор rs = stmt.executeQuery() execute() на языке СУБД API 2 2 Создание выборки (как?) Вся выборка уходит клиенту 6 6

SQL-запросы к СУБД Рассмотренные случаи – крайности Вариант серверного курсора плох тем, что каждую запись необходимо тянуть с сервера – высоки накладные расходы Клиентский курсор плох тем, что выборка может быть очень большая, невозможно держать её всю на клиенте слайд 3-58 Выводы по устройству выборок

SQL-запросы к СУБД Как правило, используется комбинированное решение – серверная выборка кешируется на клиенте Более подробную информацию необходимо смотреть в документации на драйвер – устройство выборки vendor-dependent слайд 3-59 Выводы по устройству выборок

SQL-запросы к СУБД Для классов выборок, поддерживающих кеширование, интерфейс ResultSet предлагает методы: void setFetchDirection(int) / int getFetchDirection() ResultSet.FETCH_FORWARD ResultSet.FETCH_REVERSE ResultSet.FETCH_UNKNOWN void setFetchSize(int) / int getFetchSize() слайд 3-60 Управление кешированием

Взаимодействие с СУБД Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок слайд 3-61

SQL-запросы к СУБД Рассмотренные простые выборки – это выборки: Без возможности модификации Без возможности произвольного доступа, т.е. у разработчика есть возможность двигаться только вперед (методом next() ) В данном блоке мы рассмотрим выборки с произвольным доступом Следует помнить, эта возможность может быть не реализована драйвером слайд 3-62 Выборки с произвольным доступом

SQL-запросы к СУБД Выборки с произвольным доступом дают возможность разработчику перемещаться по выборке в произвольном направлении По умолчанию создаваемые выборки – строго последовательные Интерфейс ResultSet имеет все методы перемещения, просто для последовательных выборок работает только метод next() слайд 3-63 Выборки с произвольным доступом

SQL-запросы к СУБД В интерфейсе ResultSet определены методы перемещения: boolean next() / boolean previous() boolean absolute(int) / boolean relative(int) void afterLast() / void beforeFirst() boolean last() / boolean first() слайд 3-64 Методы перемещения

SQL-запросы к СУБД Рассмотрим дополнительные методы создания запросов: Параметр rsType и определяет тип будущих выборок, полученных из этого запроса слайд 3-65 Создание выборки с произвольным доступом: Connection.createStatement(int rsType, int rsConcurrency) Connection.prepareStatement(String sql, int rsType, int rsConcurrency) Connection.prepareCall(String sql, int rsType, int rsConcurrency) Дополнительные сигнатуры методов создания запросов

SQL-запросы к СУБД Типы выборок определены как статические константы интерфейса ResultSet : ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.TYPE_SCROLL_SENSITIVE слайд 3-66 Типы выборок

SQL-запросы к СУБД ResultSet.TYPE_FORWARD_ONLY Движение по выборке – только вперед. Значение по умолчанию для создаваемых запросов ResultSet.TYPE_SCROLL_INSENSITIVE Движение по выборке – произвольное. При этом изменения, сделанные другими пользователями БД не отражаются в процессе перемещения по записям ResultSet.TYPE_SCROLL_SENSITIVE Движение по выборке – произвольное. Изменения других пользователей отражаются слайд 3-67 Типы выборок

SQL-запросы к СУБД Для получения типа существующей выборки можно воспользоваться методом getType(): int ResultSet.getType() слайд 3-68 Типы выборок

SQL-запросы к СУБД В интерфейсе ResultSet определены методы локализации: boolean isBeforeFirst() / boolean isAfterLast() boolean isFirst() / boolean isLast() int getRow() слайд 3-69 Методы локализации

SQL-запросы к СУБД Мы можем определить тип выборки при создании запроса: Последовательная выборка Выборка с произвольным доступом: Отражающая изменения, сделанные другими пользователями Не отражающая Выборки с произвольным доступом ресурсоемки слайд 3-70 Выводы по выборкам с произвольным доступом

Взаимодействие с СУБД Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок слайд 3-71

SQL-запросы к СУБД Модифицируемые выборки позволяют непосредственно в курсоре осуществлять: Добавление записей Удаление записей Модификацию записей Следует помнить, эта возможность может быть не реализована драйвером слайд 3-72 Модифицируемые выборки

SQL-запросы к СУБД Для вставки необходимо, чтобы в выборке присутствовал первичный ключ (за исключением случая автогенерации ключа) В запросе не должно быть агрегирующих функций или сортировки ( GROUP BY или ORDER BY ) Для изменения необходимо, чтобы данные выборки были из одной таблицы слайд 3-73 SQL-запрос должен удовлетворять следующим базовым критериям:

SQL-запросы к СУБД Рассмотрим методы создания запросов: Параметр rsConcurrency и определяет тип будущих выборок, полученных из этого запроса слайд 3-74 Создание модифицируемой выборки: Connection.createStatement(int rsType, int rsConcurrency) Connection.prepareStatement(String sql, int rsType, int rsConcurrency) Connection.prepareCall(String sql, int rsType, int rsConcurrency) Сигнатуры методов создания запросов

SQL-запросы к СУБД Типы выборок определены как статические константы интерфейса ResultSet : ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE слайд 3-75 Типы выборок

SQL-запросы к СУБД ResultSet.CONCUR_READ_ONLY Немодифицируемый курсор. Значение по умолчанию для создаваемых запросов ResultSet.CONCUR_UPDATABLE Модифицируемый курсор слайд 3-76 Типы выборок

SQL-запросы к СУБД слайд 3-77 Пример создания выборки: Statement statement = connection.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); ResultSet resultset = statement.executeQuery(SELECT * FROM employee); MyDBClient.java

SQL-запросы к СУБД Для модификации в текущей записи выборки следует воспользоваться методами ResultSet.updateXXX(), по аналогии с методами чтения ResultSet.getXXX() Методы модификации принимают два параметра – номер или имя поля и значение поля слайд 3-78 Модификация в выборках

SQL-запросы к СУБД Изменения в полях текущей записи не вступят в силу немедленно Для подтверждения изменений в полях необходимо вызвать метод ResultSet.updateRow() слайд 3-79 Модификация в выборках

SQL-запросы к СУБД слайд 3-80 Пример модификации в выборках: Statement statement = connection.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); ResultSet resultset = statement.executeQuery(SELECT * FROM employee); while( resultset.next() ){ double newSalary = resultset.getDouble("salary")*2; //Ура! Наконец-то! resultset.updateDouble("salary",newSalary); resultset.updateRow(); } MyDBClient.java

SQL-запросы к СУБД Для вставки записи в выбоках предусмотрена специальная системная запись, т.н. InsertRow Для вставки новой записи необходимо: Перейти на InsertRow методом ResultSet.moveToInsertRow() Обновить значения полей Подтвердить вставку методом ResultSet.insertRow() слайд 3-81 Вставка записи в выборку

SQL-запросы к СУБД слайд 3-82 Пример вставки в выборках: Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet resultSet = statement.executeQuery("SELECT * FROM employees"); resultSet.moveToInsertRow(); resultSet.updateInt("SSN", ); resultSet.updateString(name","Rebecca"); resultSet.updateDouble(salary", ); resultSet.insertRow(); MyDBClient.java

SQL-запросы к СУБД Для удаления текущей записи необходимо вызвать метод ResultSet.deleteRow() Изменения должны проявляться в курсоре и в базе одновременно Какая запись станет текущей после удаления – предыдущая или следующая, зависит от реализации драйвера слайд 3-83 Удаление текущей записи в выборке

SQL-запросы к СУБД Разработчик может непосредственно в курсоре: Изменять значения полей текущей записи Вставлять записи Удалять записи Модифицируемые выборки ресурсоемки слайд 3-84 Выводы по модифицируемым выборкам

Взаимодействие с СУБД Рассматриваемые темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок слайд 3-85

Обработка ошибок Почти каждый метод интерфейсов JDBC API возвращает один тип ошибки – SQLException SQLException наследуется от Exception Это значит, что SQLException содержит строку с описанием ошибки String getMessage() слайд 3-86 SQLException

Обработка ошибок Строку с описанием ошибки в формате X/OPEN или SQL/99 String getSQLState() Чтобы определить, в каком из форматов дана ошибка, необходимо воспользоваться метаинформацией Код ошибки, vendor-specific int getErrorCode() Следущее исключение слайд 3-87 SQLException содержит так же:

Обработка ошибок Один запрос может породить множество ошибок В этом случае JDBC-драйвер вернет цепочку исключений Для организации цепочек в объектах SQLException хранится ссылка на следующее исключение слайд 3-88 Цепочки исключений

Обработка ошибок В SQLException предусмотрены методы работы со следующим исключением: SQLException getNextException() void setNextException(SQLException) слайд 3-89 Цепочки исключений

Обработка ошибок слайд 3-90 Пример работы с цепочкой исключений: try { //Бизнес-логика omitted } catch( SQLException e ) { while( e != null ) { //Обрабатываем исключение //Анализируем e.getSQLState() //Анализируем e.getErrorCode() e = e.getNextException(); } MyDBClient.java

Обработка ошибок На каком этапе необходимо закрывать курсоры, запросы и соединения? Следует помнить, что методы закрытия так же могут инициировать исключение слайд 3-91 Исключения и освобождение ресурсов try { //Работа с БД } catch( SQLException e ) { }

Обработка ошибок слайд 3-92 Полный пример по исключениям: // Объявления переменных соединения, запроса, выборки именно здесь, до блока try try { //Бизнес-логика omitted } catch( SQLException se ) { while( se != null ) { // Цикл по цепочке исключений //se.printStackTrace(); - Только для отладки! System.out.println( "Ошибка SQL: " + se.getErrorCode() + ", " + se.getMessage() ); se = se.getNextException(); } } catch( Exception e ) { //Например, ClassNotFoundException System.out.println( "Ошибка " + e.getMessage() ); } finally { try { if( connection!=null ) connection.close(); } catch( SQLException se ) { System.out.println( "Ошибка SQL: " + se.getMessage() ); } MyDBClient.java

Обработка ошибок слайд 3-93 Выводы по исключениям: // Объявления переменных соединения, запроса, выборки именно здесь, до блока try try { //Бизнес-логика omitted } catch( SQLException se ) { while( se != null ) { // Цикл по цепочке исключений //se.printStackTrace(); - Только для отладки! System.out.println( "Ошибка SQL: " + se.getErrorCode() + ", " + se.getMessage() ); se = se.getNextException(); } } catch( Exception e ) { //Например, ClassNotFoundException System.out.println( "Ошибка " + e.getMessage() ); } finally { try { if( connection!=null ) connection.close(); } catch( SQLException se ) { System.out.println( "Ошибка SQL: " + se.getMessage() ); } MyDBClient.java

Обработка ошибок Помимо ошибок, JDBC API регламентирует понятие предупреждения Предупреждения реализованы классом SQLWarning SQLWarning – наследник SQLException Но предупреждения не прерывают выполнение программы слайд 3-94 Предупреждения, Warnings

Обработка ошибок Предупреждения не выбрасываются методами интерфейсов JDBC API Их необходимо вручную «вытягивать» их из соединений, запросов, курсоров SQLWarning Connection.getWarnings() SQLWarning Statement.getWarnings() SQLWarning ResultSet.getWarnings() В случае отстутствия предупреждений методы возвращают null слайд 3-95 Предупреждения

Обработка ошибок «Вытягивать» предупреждения необходимо до закрытия объектов соединения, запроса, выборки Предупреждения, как и ошибки, образуют цепочки SQLWarning SQLWarning.getNextWarning() void SQLWarning.setNextWarning(SQLWarning) Работа с цепочками производится, как и в случае SQLException слайд 3-96 Предупреждения

Обработка ошибок В некоторых случаях необходимо очистить предупреждения после их обработки Методы очистки: void Connection.clearWarnings() void Statement.clearWarnings() void ResultSet.clearWarnings() слайд 3-97 Предупреждения

Обработка ошибок Предупреждения самой СУБД Установка свойств, не поддерживаемых драйвером Уровень изоляции транзакций Курсор с произвольным доступом Модифицируемый курсор слайд 3-98 Ситуации, приводящие к предупреждениям

Взаимодействие с СУБД Рассмотренные темы: SQL-запросы к СУБД Обработка данных из БД, выборки Выборки с произвольным доступом Модифицируемые выборки Обработка ошибок слайд 3-99