Java JDBC: Работа с базой данных
Теория: Общие принципы работы
В этом курсе мы погрузимся в различные элементы JDBC, но сначала рассмотрим общие принципы, которые работают одинаково для любых запросов. Эти принципы включают такие пункты:
- Установка зависимостей
- Подключение к базе данных
- Подготовка запроса
- Выполнение запроса
- Формирование результата
В этом курсе мы будем работать с базой данных H2. Она полноценно работает с SQL, но есть одно отличие — ее можно создавать только в памяти, что удобно для обучения и тестирования. При необходимости вы с легкостью можете заменить ее на любую полнофункциональную базу.
Подключение базы H2 выполняется одной строчкой:
Далее в уроке мы рассмотрим основной принцип работы с JDBC на примере работы с таблицей пользователя. Для начала создадим таблицу в коде, заполним ее и выведем ее данные в консоль:
Исключения
Методы для работы с базой данных выбрасывают исключения, которые входят в иерархию классов с базовым исключением SQLException. Поэтому мы должны обращать особое внимание на методы, работающие с запросами. Нужно помечать их как методы, выбрасывающие этот вид исключений:
Соединение с базой данных
Обычно программисты делают так: рядом со своим приложением они поднимают СУБД, внутри которой они заранее создали необходимую базу данных. Таким образом, приложение соединяется с СУБД и подключается к конкретной базе данных внутри. Для этого нужны параметры подключения:
- IP-адрес или DNS-адрес
- Порт для подключения
- Логин и пароль
- Имя базы данных
В нашем примере все проще. База H2 запускается прямо в памяти нашего приложения, поэтому ей не нужны доступы. Эту базу не нужно создавать заранее, она создается в момент выполнения соединения:
Дальше мы можем работать с базой H2 с помощью SQL.
Здесь все как с обычной реляционной базой данных. Но важно помнить, что эта база существует, только когда приложение запущено. Если мы остановим или перезапустим приложение, это приведет к потере данных. Это нормально для учебных и тестовых задач, но не подходит для реальных приложений, поэтому в них база H2 не используется.
Стейтмент
В коде выше перед выполнением запроса мы создали стейтмент, а затем закрыли его. Далее мы обсудим, какую роль стейтмент играет в этом процессе, но сначала рассмотрим такой код:
Выполнение запроса в базу данных — это более сложная операция, чем кажется на первый взгляд.
Для примера представим, что мы делаем запрос на выборку данных. В этом случае мы вручную пересылаем выборку из базы в приложение, потому что база передает данные только по запросу. Почему это не происходит автоматически? Дело в том, что выборка может быть огромной, тогда автоматическая пересылка привела бы к резкому скачку использования оперативной памяти.
У этой особенности есть неочевидная обратная сторона — дополнительная память начинает активно использоваться внутри самой базы данных.
Чтобы этого не происходило, мы должны четко обозначить отрезок времени, в который СУБД должна хранить запрошенные данные. Именно по этой причине нам приходится закрывать стейтменты. Когда мы это делаем, JDBC посылает сигнал базе данных, обозначая, что данные больше не нужны. В ответ на этот сигнал, база данных освобождает ресурсы.
Может показаться, что мы переложили проблему с клиента на сервер, но это не совсем так. Базы данных стараются максимально оптимизировать работу с данными, поэтому они затрачивают меньше ресурсов на хранение выборок ниже. К тому же, передача данных по сети — это долго и дорого.
А что будет, если не закрыть стейтмент? Стейтменты удерживают ресурсы системы — если забывать их закрывать, то в итоге это приведет к сбоям в работе приложения.
Вернемся к примеру выше. В нем можно увидеть, что на каждый тип запроса внутри стейтмента выполняется свой собственный метод по такой схеме:
- Запросы на выборку данных выполняются через метод
stmt.executeQuery() - Запросы на вставку и обновление данных работают через метод
stmt.executeUpdate() - Все остальные запросы через метод
stmt.execute()— в нашем примере это создание таблицы
Объекты класса ResultSet
Последний элемент нашего примера — это ResultSet:
Объекты этого класса выполняют роль курсора — указателя на набор данных, хранящийся в памяти в базе. Другими словами, это не набор извлеченных данных из базы, это всего лишь указатель на них. Кроме того, курсор может последовательно перебирать данные через метод next(). Вызов этого метода приводит к тому, что содержимое объекта подменяется новой порцией данных от СУБД.
Извлечение данных из курсора требует преобразования типов, потому что типы данных в базе далеко не всегда совпадают с типами в Java. Поэтому при получении данных мы должны знать, в какой тип мы хотим преобразовать их.
Также отметим, что ResultSet тоже имеет метод close(), но он используется редко. Обычно ResultSet закрывается автоматически при закрытии стейтмента.
Рекомендуемые программы
Завершено
0 / 5

