Elettracompany.com

Компьютерный справочник
3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java sql statement

Класс Statement

Statement используется для выполнения SQL-запросов. Существует три типа класса Statement, которые являются как бы контейнерами для выполнения SQL-выражений через установленное соединение:

  • Statement, базовый;
  • PreparedStatement, наследующий от Statement;
  • CallableStatement, наследующий от PreparedStatement.

Все классы специализируются для выполнения различных типов запросов:

  • Statement предназначен для выполнения простых SQL-запросов без параметров; содержит базовые методы для выполнения запросов и извлечения результатов.
  • PreparedStatement используется для выполнения SQL-запросов с или без входных параметров; добавляет методы управления входными параметрами.
  • CallableStatement используется для вызовов хранимых процедур; добавляет методы для манипуляции выходными параметрами.

Создание объектов Statement

После установления соединения Connection с базой данных, оно может использоваться для выполнения SQL-запросов. Объект Statement создается методом Connection.createStatement.

Пример :

Для отправки серверу БД SQL-выражения для выполнения необходимо вызвать метод executeQuery объекта Statement и в качестве аргумента передать скрипт запроса :

Методы Statement : executeQuery, executeUpdate, execute

Класс Statement содержит три различных метода выполнения SQL-выражений : executeQuery, executeUpdate и execute, которые вызываются в зависимости от текста SQL-запроса.

executeQuery

Метод executeQuery используется в запросах, результатом которых является один единственный набор значений, таких как запросов типа SELECT.

executeUpdate

Метод executeUpdate следует использовать, как для выполнения операторов управления данными типа INSERT, UPDATE или DELETE (DML — Data Manipulation Language), так и для операторов определения структуры базы данных CREATE TABLE, DROP TABLE (DDL — Data Definition Language).

Результатом выполнения операторов INSERT, UPDATE, или DELETE является изменения одной или более строк таблицы.

Результатом выполнения метода executeUpdate является целочисленное значение, определяющее, сколько строк было модифицировано. Для выражений DML, которые не оперируют со строками, возвращаемое методом executeUpdate значение всегда равно нулю.

execute

Метод execute используется, когда операторы SQL возвращают более одного набора данных, более одного счетчика обновлений или и то, и другое. Такая возможность редко используется программистами.

Объекты Statement сами по себе не «помнят» SQL-выражение. Оно передается в качестве аргумента методов Statement.executeXXX.

Необходимо отметить, что PreparedStatement, наследующий все методы Statement, имеет свои реализации методов executeQuery, executeUpdate и execute. Объекты PreparedStatement не принимают SQL-выражения в виде аргументов этих методов, так как они уже содержат прекомпилированные SQL-выражения.

CallableStatement наследуют методы от PreparedStatement без параметров. Использование аргументов в методах executeXXX объектов PreparedStatement и CallableStatement приведет к генерации ошибки SQLException.

Объекты Statement закрываются автоматически сборщиком мусора виртуальной машины Java. Тем не менее рекомендуется закрывать их явно после того, как работа с ними завершена. Закрытие объектов Statement после их использования освобождает ресурсы СУБД и позволяет избежать проблем с памятью.

Завершение выполнения запросов

Объект Statement считается завершенным (complete), если он выполнился и все его результаты были возвращены.

Для метода executeQuery, возвращающий набор данных, оператор считается завершенным, если считаны все строки соответствующего объекта ResultSet. В случае использования метода executeUpdate объект завершен сразу же после выполнения метода.

В случае вызова метода execute оператор остается не завершенным до тех пор, пока все наборы данных не будут считаны.

Использование PreparedStatement

PreparedStatement предварительно компилирует запросы, которые могут содержать входные параметры обозначенные символом ‘?’

Пример использования PreparedStatement

Использование CallableStatement

Объект CallableStatement предоставляет унифицированный способ вызова хранимых процедур в СУБД. Вызов процедуры осуществляется с результирующим параметром и без него. Результирующий параметр — это один из типов выходных (OUT) параметров, являющийся возвращаемым значением хранимой процедуры.

Синтаксис вызова хранимой процедуры в JDBC показан ниже. Квадратные скобки означают, что то, что находится между ними, необязательно, и сами по себе не являются частью синтаксиса.

Первые две формы могут иметь переменное число аргументов на входе (параметры IN), выходе (параметры OUT) или входных и выходных параметров одновременно (INOUT-параметры). Вопросительный знак означает местоположение параметра.

Метод supportsStoredProcedures() класса DatabaseMetaData позволяет узнать, поддерживает СУБД хранимые процедуры или нет.

Создание объекта CallableStatement

Объекты CallableStatement создаются методом prepareCall объекта Connection. Пример, который создает экземпляр CallableStatement, содержащий вызов хранимой процедуры setGoodsData с двумя аргументами и без возвращаемого параметра:

Какими именно параметрами (IN, OUT или INOUT) являются знаки вопроса — зависит от самой хранимой процедуры setGoodsData.

Входные и выходные IN- и OUT-параметры

Передача значений входных парметров объекта CallableStatement осуществляется с помощью методов setXXX, унаследованных от PreparedStatement. Типы передаваемых значений определяются тем, какой из методов setXXX используется (setString для передачи значений типа String, setInt для передачи значений типа int и т.п.).

JDBC-типы всех OUT-параметров хранимых процедур должны быть зарегистрирваны перед их вызовом. Регистрация типов данных выходного параметра производится методом registerOutParameter. Только в этом случае после вызова хранимой процедуры CallableStatement.executeQuery() можно получить результаты выполнения с помощью методов getXXX. Необходимо использовать подходящий по типу данных Java метод getXXX в соответствии с зарегистрированным JDBC-типом параметра. Другими словами, registerOutParameter использует JDBC-тип, который подходит к JDBC-типу возвращаемого из значения, а getXXX преобразует его в тип Java.

Пример регистрации выходных параметров хранимой процедуры и чтение выходных значений. В примере метод getByte извлекает байт из первого выходного параметра, а getBigDecimal возвращает объект BigDecimal (с двумя цифрами после десятичной точки) из второго выходного параметра :

Чтение выходных параметров

В связи с ограничениями некоторых СУБД для большей совместимости рекомендуется сначала считывать результаты, сгенерированные вызовом CallableStatement, а затем выходные (OUT) параметры.

Если объект CallableStatement возвращает несколько объектов ResultSet (с использованием метода execute), то ВСЕ результаты должны быть прочитаны перед первым обращением к выходным параметрам. В этом случае для того, чтобы прочитать все результаты, надо последовательно вызывать методы Statement getResultSet, getUpdateCount и getMoreResults до тех пор, пока не останется больше результатов. После этого значения выходных параметров могут быть извлечены спомощью методов CallableStatement.getXXX.

Нулевое значение в выходных параметрах, wasNull

Возращаемое значение в выходном параметре может быть NULL. При этом методы getXXX возвращают null, 0 или false, в зависимости от типа данных.

Как и в случае с ResultSet, единственным способом узнать, вернула ли процедура 0, false или NULL, является вызов метода wasNull, который возвращает true, если последнее значение, считанное одним из методов getXXX был NULL, и false иначе.

Входные/выходные параметры INOUT

Если параметр является одновременно и входным, и выходным (INOUT), то необходимо вызывать как метод setXXX, так и метод registerOutParameter. Метод setXXX устанавливает входное значение параметра, а registerOutParameter регистрирует тип выходного значения.

Типы входного и выходного значений, зарегистрированных методом registerOutParameter, должны быть одинаковыми. Для чтения выходного значения используется соответствующий метод getXXX. Например, для параметра типа byte нужно использовать метод установки значения setByte, передавать JDBC-тип данных TINYINT методу registerOutParameter и использовать getByte для чтения выходного значения.

В следующий пример демонстрирует вызов хранимой процедуры rebuildTotal с одним INOUT-параметром. Метод setByte устанавливает значение параметра в 25, которое будет передано хранимой процедуре базе данных как TINYINT. Далее метод registerOutParameter регистрирует 1-ый параметр как TINYINT. После выполнения хранимой процедуры возвращается значение типа TINYINT, которое будет считано методом getByte в виде типа byte языка Java.

Читать еще:  Как восстановить панель управления на рабочем столе

Если хранимая процедура оформлена функцией, т.е возвращает значение не через параметры, а через оператор «RETURNS», то для вызова используйте «execute» вместо «executeUpdate».

В отличие от ResultSet, CallableStatement не может считывать большие значения последовательно (в потоке)..

Escape-последовательности в запросах Statement

SQL-выражения Statement‘ов могут включать escape-последовательности, которые сигнализирует о том, что код выражения должен обрабатываться особо. Escape-последовательности заменяются кодом, специфичным для данной СУБД. Escape-синтаксис независит от типа СУБД

Cинтаксис escape-последовательности

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

Ключевое слово индицирует вид Escape-конструкции.

1. escape-последовательность с символом

Операция SQL типа LIKE использует шаблонные символы «%» и «_», которые используются для извлечения информации с определенными символами. Чтобы эти символы интерпретировались в SQL-выражении без изменений, необходимо перед ними установить обратный символ слэша «». Этот специальный символ и называется escape-символом.

Можно явно определить, какой именно из символов использовать в качестве escape-символа, если в конце запроса ввести следующую конструкцию:

В следующем коде осуществляется чтение строки, начинающейся со знака подчеркивания:

2. escape-последовательность с функциией fn

Практически во всех СУБД есть функции для манипуляции с числами, строками, временем, датой. Эти функции могут использоваться в escape-конструкции с ключевым словом fn, именем функции и ее аргументами. Следующий пример вызывает функцию конкатенации concat с двумя аргументами:

Имя текущего пользователя БД может быть извлечено с помощью следующего вызова:

Скалярные функции могут поддерживаться различными СУБД с немного отличающимся синтаксисом, а некоторыми СУБД могут и не поддерживаться вовсе.

Для получения списка поддерживаемых СУБД функций можно использовать класс чтения метаданных DatabaseMetaData, у которого метод getNumericFunctions возвращает список имен числовых функций, разделенных запятой, а метод getStringFunctions возвращает строковые функции, и т.д.

3. escape-последовательность для работы с датой и временам

Различные СУБД отличаются форматом записи и чтения даты, времени и временного штампа, включающего дату и время (timestamp).

Формат использование escape-последовательности даты следующий:

где yyyy — это год, mm — месяц, и dd — день. Например, следующая последовательность будет заменена строкой ’28- FEB-15′, если СУБД воспринимает именно такой формат даты.

Аналогичным образом обрабатываются escape-конструкции для типов данных TIME и TIMESTAMP:

Милисекунда (.ms) в TIMESTAMP может быть опущена.

4. escape-последовательность с хранимыми процедурами

Для обращения к хранимой процедуры из JDBC используется либо call, либо ? = call.

Если СУБД поддерживает хранимые процедуры, то они могут вызываться из JDBC с помощью следующего синтаксиса escape-последовательности:

Руководство по JDBC. Утверждения (Statements).

В прошлом уроке мы изучили что такое соединение и способы его создания.
После того, как соединение было утсановлено, мы можем начинатть взаимодействие с базой данных (далее – БД).
Взаимодействовать с БД мы можем с помощью трёх интерфейсов, которые имплементируются каждым драйвером:

  • Statement
    Этот интерфейс используется для доступа к БД для общих целей. Он крайне полезен, когда мы используем статические SQL – выражения во время работы программы. Этот интерфейс не принимает никаких параметров.
  • PreparedStatement
    Этот интерфейс используется в случае, когда мы планируем использовать SQL – выражения множество раз. Он принимает параметры во время работы программы.
  • CallableStatement
    Этот интерфейс становится полезным вслучае, когда мы хотим получить досутп к различным процедурам БД. Он также может прнимать параметры во время работы программы.

Создание экземпляра Statement

Прежде, чем мы сможем использовать экземпляр Statement для выполнения SQL – запросов, нам необходимо создать такой экземпляр. ДЛя этого используется метод Connection.createStatement(). В коде это выглядит таким образом:

После этго мы можем использовать наш экземпляр statement для выполнения SQL – запросов.

Для этой цели интерфейс Statement имеет три метода, которые реализуются каждой конкретной реализацией JDBC драйвера:

  • boolean execute (String SQL)
    Этот метод возвращает логическое значение true, если объект ResultSet может быть получен. В противном случае он вовращает false. Он используется для выполнения DDL SQL – запросов ил в случаях, когда мы используем динамический SQL.
  • int executeUpdate (String SQL)
    Этот метода возвращает количесство столбцов в таблице, на которое повлиял наш SQL – запрос. Мы используем этот метод для выполнения SQL – запросов, когда хотим получить количество задействованных столбцов, например количество данных по определённому запросу.
  • ResultSet executeQuery (String SQL)
    Этот мтеод возвращает нам экземпляр ResultSet. Мы используем этот метод в случаях, когда мы рассчитываем получить множество объектов в результате выполнения нашего SQL – запроса. Например, при получении списка элементов, которые удовлетворяют опредлённым условиям.

Закрытие экземпляра Statement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экpемпляр Statement.

Для этого мы испольузем метод close().

Рассмотрим, как это выглядит в нашем коде:

Для понимания того, как это работает на практике, рассмотрим пример простого приложения, в котором мы попытаемся получить данные из БД.

В результате работы программы мы получим следующий результат:

Создание экземпляра PreparedStatement

PreparedStatement наследует интерфейс Statement, что даёт нам опредёлнные преимущества перед обычным Statement. В частности, мы получаем большую гибкость при динамичской поддержке аргументов.

Вот как выглядит создание экземпляра PreparedStatement на практике:

Все параметры, которые отмечены символом ? называются маркерами параметра. Это означает, что они должны быть переданы через параметры метода.

Каждый параметр ссылается на свой порядковый номер в сигнатуре метода. Т.е. первый маркер находится на первом месте, второй – на втором и т.д. В отличие от массивов, здесь отсчёт идёт с 1. Это связано с особенностями реляционной модели, на которой и основана работа реляционных БД.

Для выполнения SQL – запросов используются методы с такими же названиями (execute(), executeQuery, executeUpdate), которые несколько модифицированы.

Закрытие экземпляра PreparedStatement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экземпляр PreparedStatement.

Для этого мы испольузем метод close().

Рассмотрим, как это выглядит в нашем коде:

Для понимания того, как это работает на практике, рассмотрим пример простого приложения с использованием PreparedStatement.
Пример:

В результате работы программы мы получим, примерно, следующий результат:

В этом приложении мы сначала получаем и выводим в консоль список всех записей из таблицы developer, после чего устанавливаем salary = 3000 для всех разработчиков, у которых specialty = “Java”.

Создание экземпляра CallableStatement

Экземпляр CallableStatement используется для выполнения процедур, непосредоственно в самой БД.

Рассмотрим пример, в котором нам необходимо выполнить такую процедуру в MySQL:

Существует три типа параметров: IN, OUT, INOUT. PreparedStatement использует только IN, а CallableStatement, в свою очередь, использует все три.

Читать еще:  Удалить данные восстановления и перейти к загрузке

Рассмотрим, что же это за параметры:

  • IN
    Параметр, значение которого известно в момент, когда создаётся запрос. Мы назначем параметр IN с помощью метода типа setXXX().
  • OUT
    Параметр, значение которого возвращается SQL – запросом. Мы получаем значения из OUT с помощью методов типа getXXX().
  • INOUT
    Параметр, который использует входные и выходные значения. Мы назначем параметр с помощью метода типа setXXX(), а получаем значения, с помощью метода типа getXXX().

В коде, создание экземпляра CallableStatement выглядит следующим образом:

Строка SQL представляет собой процедуру, с параметрами.

Схожим с PreparedStatement способом, мы, используя экземпляр CallableStatement, должны установить значения параметров.

Когда мы используем параметры типа OUT и INOUT, нам необходимозадействовать дополнительный метод registerOutParameter(). Этот метод устанавливает тип данных JDBC в тип данных процедуры.

После того, как мы вызвали рпоцедуру, мы получаем значение из параметра OUT с помощью соответствующего метода getXXX(). Этот метод преобразует полученное значение из типа дыннх SQL в тип данных Java.

Закрытие экземпляра CallableStatement

Когда мы закрываем наше соединение (Connection) для сохранения результатов в БД мы таким же образом закрываем и экземпляр Statement.

Для этого мы испольузем метод close().

Рассмотрим, как это выглядит в нашем коде:

Для понимания того, как это работает на практике, рассмотрим пример простого приложения
Пример:

Создаём процедуру в нашей БД:

В результате работы программы мы получим следующий результат:

В этом уроке мы изучили утверждения (statements) их виды и рассмотрели примеры приложений с их использованием.

В следующем уроке мы изучим такой элемент, как Result Set.

Java sql statement

В предыдущей статье мы только познакомились с JDBC и написали простое приложение, которое позволило нам соединиться с СУБД и получить данные с помощью SQL-запроса. Хоть программа и не очень сложная, но на мой взгляд, мы сделали весьма важный шаг — мы смогли соединиться с базой данных и сделать пусть и простой, но запрос. Все, что мы рассмотрим дальше — это уже более удобные и более профессиональные способы использования JDBC.

Запросы на получение данных и запросы на обновление

SQL-запросы можно условно разделить на две группы:

  1. Получение данных — к ним относится оператор SELECT
  2. Изменение данных — к ним относятся операторы INSERT, UPDATE и DELETE

Для первой группы используется уже знакомый нам метод интерфейса StatementexecuteQuery(). В принципе для начала этого метода вполне достаточно. Он покрывает очень большой процент запросов, которые разрабатываются для реальных систем. Позже мы познакомимся с дополнительными возможностями, но на данных момент советую запомнить — если надо получить данные из таблицы, то executeQuery в подавляющем большинстве случаев будет самым правильным выбором.
Для второй группа запросов (опять же в большинстве случаев) может использоваться другой метод интерфейса StatementexecuteUpdate(). Есл посмотреть документацию, то в отличии от executeQuery() (который возвращает ResultSet) этот метод возвращает целое число, которое говорит сколько строк в таблице было изменено при исполнении вашего запроса.
Например, вы можете оператором DELETE FROM JC_CONTACT удалить ВСЕ строки (посему будьте очень аккуратны). В этом случае метод executeUpdate() вернет количество удаленных строк. В некоторых ситуациях знание о количестве измененных строк бывает удобным для построения алгоритмов работы с данными.
В принципе с этим вопросов можно закончить — главное мы уже увидели. Для выборки данных — executeQuery(). Для изменения данных — executeUpdate().

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

Самый простой интерфейс Statement мы уже видели. И хотя он вполне пригоден для работы, для сложных запросов он подходит не так хорошо. В некоторых источниках высказывается мнение, что использовать Statement вообще не надо — вместо него подходят более сложные и более функционально насыщенные интерфейсы.

Возникает вполне резонный вопрос — а зачем эти интерфейсы нужны ? Давайте разбираться. Для начала мы рассмотрим интерфейс PreparedStatement и другие возможности JDBC. К интерфейсу CallableStatement обратимся позже — его использование во-первых не так часто встречается, и во-вторых — после всего рассмотренного, про него разговор уже можно делать достаточно коротким.

PreparedStatement

Если честно перевести название, то можно получить что-то вроде «подготовленный оператор». Самым важным здесь является слово «подготовленный». В чем же заключается «подготовленность» ?
Прежде чем мы рассмотрим этот вопрос, предлагаю увидеть достаточно важный с точки зрения удобства момент, который возникает очень часто. Итак, в каком-либо приложении нам надо вставить данные о контакте в таблицу JC_CONTACT. Для этого нам надо подготовить запрос наподобие такого:

Как использовать базу данных MySQL в Java

    Переводы, 24 июня 2015 в 13:46

В этой статье мы научимся подключаться к базе данных MySQL из Java-кода и выполнять простые запросы для получения и обновления данных. Для того, чтобы получить доступ к базе данных, мы будем использовать JDBC (Java Database Connectivity) API, который входит в стандартную библиотеку Java. JDBC позволяет подключиться к любой базе данных: Postgres, MySQL, SQL Server, Oracle и т. д. — при наличии соответствующей реализации драйвера, необходимого для подключения. Для базы данных MySQL мы будем использовать драйвер Type 4 JDBC из пакета mysql-connector-java-5.1.23-bin.jar . Он написан на чистой Java, а значит, нам не понадобятся какие-либо нативные библиотеки или ODBC-мост. Все, что нам надо будет сделать — это положить JAR-файл в директорию, содержащуюся в CLASSPATH. JAR-файл содержит класс com.mysql.jdbc.Driver , необходимый для подключения к MySQL. Если его не окажется в CLASSPATH, во время выполнения программы выбросится исключение java.lang.ClassNotFoundException , поэтому убедитесь, что вы правильно настроили пути.

Кстати, если вы ищете хорошую книгу по использованию JDBC, обратите внимание на Practical Database Programming with Java (Ying Bai). Это относительно новая книга, и в ней рассматриваются две самые популярные базы данных: Oracle и SQL Server 2008. В книге используется IDE NetBeans для примеров и описываются все инструменты, необходимые для работы с базами данных в Java. Это отличная книга для начинающих и опытных программистов.

Подключаем базу данных MySQL с помощью JDBC

Для того, чтобы подключить базу данных MySQL, нам потребуется четыре вещи:

  1. Строка подключения JDBC (например: jdbc:mysql://localhost:3306/test ).
  2. Имя пользователя (root).
  3. Пароль (root).
  4. База данных с некоторым количеством таблиц для примера (например, база данных книг).

Строка подключения для MySQL начинается с jdbc:mysql . Это название протокола соединения, за которым следуют хост и порт подключения, на которых запущена база данных. В нашем случае это localhost с портом по умолчанию 3306 (если вы его не поменяли при установке). Следующая часть — test — имя базы данных, которая уже существует в MySQL. Мы можем создать таблицу Books :

Читать еще:  Восстановление удаленных файлов с жесткого диска windows

и наполнить ее хорошими книгами:

Программа на Java, которая использует базу данных

Теперь давайте напишем программу на Java, которая будет подключаться к нашей базе данных, запущенной на localhost . Важно помнить о том, что необходимо закрывать соединение, запросы и результат выполнения после завершения работы с ними. Также важно закрывать их в finally-блоке, со своей try/catch оберткой, поскольку сам метод close() может кинуть исключение, что приведет к утечке ресурсов. За подробной информацией вы можете обратиться к этой статье. Кроме того, вы можете использовать обертку try-with-resource, которая появилась в Java 7. Более того, это стандартный способ работы с ресурсами в Java 1.7.

При первом запуске у вас, возможно, будет ошибка No suitable driver found for jdbc:mysql , если драйвера MySQL нет в CLASSPATH:

Добавим нужный JAR-файл в путь и снова запустим программу. Другая частая ошибка — указать таблицу в строке соединения: jdbc:mysql://localhost:3306/test/book . В этом случае вылетит следущее исключение:

Успешный запуск программы выведет на экран следующее:

Результат верный, поскольку у нас в таблице только две книги: «Effective Java» и «Java Concurrency in Practice».

Кстати, если у вас был драйвер при компиляции, но отсутствует при запуске, вы получите исключение java.lang.ClassNotFoundException: com.mysql.jdbc.Driver . О том, как исправить эту ошибку, вы можете прочитать здесь.

Получаем данные с помощью SELECT-запроса в JDBC

Для получения данных из БД вы можете выполнить SELECT-запрос. В первом примере мы уже его использовали, но получили только количество строк. Теперь мы вернем сами строки. Большая часть программы останется без изменений, за исключением SQL-запроса и кода, возвращающего данные из объекта ResultSet :

Этот код выведет на экран следующее:

Тут есть пара моментов, на которые следует обратить внимание. Метод rs.getInt(1) используется для получения столбца с целочисленным типом, в нашем случае это столбец «id». Индексы в JDBC начинаются с единицы, поэтому rs.getInt(1) вернет значение первого столбца как целое число. В случае, если вы укажете неверный индекс (многие разработчики вызывают rs.getInt(0) для получения первого столбца), выбросится исключение InvalidColumnIndexException . Доступ к столбцам по индексу чреват ошибками, поэтому лучше использовать имя столбца, например, rs.getInt(«id») . Подробнее об этом вы можете прочитать в этой статье. Метод getString() используется для получения строковых значений из базы (например, VARCHAR ). Цикл будет выполняться, пока rs.next() не вернет false . Это значит, что строки закончились. В нашем случае в таблице две строки, поэтому цикл выполнится два раза, выводя информацию о книгах из таблицы на экран.

Добавляем данные с помощью INSERT-запроса в JDBC

Добавление данных мало отличается от их получения: мы просто используем INSERT-запрос вместо SELECT-запроса и метод executeUpdate() вместо executeQuery() . Этот метод используется для запросов INSERT, UPDATE и DELETE, а также для SQL DDL выражений, таких как CREATE, ALTER или DROP. Эти команды не возвращают результата, поэтому мы убираем все упоминания ResultSet ‘а в коде и изменяем запрос соответственно:

После запуска программы вы можете проверить таблицу в СУБД. На этот раз вы увидите три записи в таблице:

Теперь вы умеете подключаться к MySQL из Java-приложения и выполнять SELECT, INSERT, DELETE и UPDATE-запросы так же, как и в MySQL GUI. Для подключения мы используем объект Connection , для чтения результатов запроса — ResultSet . Убедитесь перед подключением, что сервер MySQL запущен и mysql-connector-java-5.1.17-bin.jar находится в CLASSPATH, чтобы избежать ClassNotFoundException .

Когда разберетесь с подключением и простыми запросами, имеет смысл изучить, как использовать подготавливаемые запросы (Prepared Statement) в Java для избежания SQL-инъекции. В боевом коде всегда следует использовать подготавливаемые запросы и связывание переменных.

Работа с SQL в Java

Материал из BiTel WiKi

Описание

Работа с базами данных в Java осуществляется через JDBC (Java Database Connectivity) — API доступа к базам данных. JDBC — набор интерфейсов, которые реализуются драйвером БД. Наиболее важные интерфейсы JDBC — java.sql.Connection, java.sql.Statement, java.sql.PreparedStatement, java.sql.ResultSet.

Драйвер БД — специальная библиотека, реализующая интерфейсы JDBC для работы с конкретной СУБД. Для MySQL драйвер может быть загружен здесь: [1].

  • Connection — интерфейс — соединение с базой данных.
  • Statement — специальный интерфейс для выполнения SQL запросов.

У интерфейса Statement для выполнения запросов обычно используются 3 функции: executeUpdate выполняет запросы на вставку и изменение (INSERT и UPDATE) и возвращает количество измененных/добавленных строк, executeQuery — выполняет выборку (SELECT) и возвращает объект ResultSet, содержащий результат выборки, а также execute выполняет sql запрос и возвращает true, если запрос был на выборку и false, если запрос был на изменение (результат выполнения можно получить st.getResultSet() для выборки и st.getUpdateCount() для изменения).

Интерфейс PreparedStatement расширяет Statement и используется для прекомпилируемых sql запросов. Он используется при множественном выполнении одного и того же запроса (с одинаковыми илил разными параметрами).

После создания PreparedStatement можно выполнять много раз:

Пул соединений

При работе приложения обычно происходит частое создание Connection, выполнение запросов, а потом их закрытие. Физически это бы означало что каждый раз при этом создавалось новое TCP соединение с базой, а после уничтожалось. Чтобы не тратить время на установление нового соединиения (а также создание нового объекта Connection) используются так называемый connection pool — пул соединений. Работает он очень просто — при запросе на закрытие соединения он его не закрывает а всего лишь очищает от информации полученной при работе с этим соединением. При следующем вызове на получение Connection пул выдает данный и мы работаем с ним как с новым. Если же в текущий момент соединений хранимых в пуле нет то он создает новый. Обычно выставляется ограничение на максимальное количество соединений хранимых в пуле.

Существуют готовые средства для реализации пулов соединений. Далее пример класса реализующего пул и основанного на GenericObjectPool от apache.org. Для работы данного примера необходимы библиотеки [2], | commons-dbcp. Первая предоставляет набор интерфейсов для работы с пулами + их абстрактные реализации. Вторая — реализация пулов для работы с соединениями к БД.

Connection полученный из пула должен обязательно быть возвращен в пул!

Пока ResultSet не будет закрыт ( close() ), связанная с ним информация будут храниться в памяти, тоже самое качается Statement, PreparedStatement, Connection. но нужно помнить что при закрытии Statement/PreparedStatement закрываются все созданные ими ResultSet, а при закрытии Connection автоматически закрываются созданные им Statement и PreparedStatement. При возвращении в пул connection закрывается.

При работе с базами данных удобно использовать паттерн DAO (Data Access Object — объект доступа к данным). При данном подходе создается класс — модель отражающий какую либо сущность (его также называют business model/object) и класс — DAO, который умеет работать с данной сущностью с базой данных:

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector
×
×