Лекции 2025. Java. Белая / Ответы на билеты. Java
.pdf
Naming and Directory Interface).
В автономных приложениях или с использованием фреймворков
(например, Spring):
может быть сконфигурирован программно или через конфигурационные файлы. Популярные реализации
с пулом соединений включают HikariCP, Apache Commons DBCP, C3P0.
Получение соединения из
:
Когда вы вызываете
на соединении, полученном из пула через
, соединение обычно не закрывается физически, а возвращается обратно в пул для переиспользования.
Общие шаги для установления соединения:
1.Убедитесь, что JDBC-драйвер доступен: JAR-файл драйвера должен быть в classpath.
2.Соберите необходимую информацию: JDBC URL, имя пользователя, пароль.
3.Используйте
или 
для получения объекта
.
4.Обработайте
: Операция подключения может выбросить
, если что-то пойдет не так (неправильный URL, неверные учетные данные, сервер БД недоступен, драйвер не найден и т.д.).
5.Всегда закрывайте
: После завершения работы с базой данных соединение должно быть закрыто в блоке
или с помощью 
(так как
реализует
), чтобы освободить ресурсы.
Для большинства новых приложений, особенно тех, что работают в многопользовательской или серверной среде, использование
с пулом соединений является стандартом де-факто из-за преимуществ в производительности и управлении ресурсами.
больше подходит для простых утилит, тестовых программ или очень небольших приложений.
82. Какие уровни изоляции транзакций поддерживаются в JDBC?
Уровни изоляции транзакций определяют, насколько одна транзакция изолирована от изменений, производимых другими параллельно выполняющимися транзакциями. JDBC позволяет устанавливать уровни изоляции для соединений с базой данных, если СУБД их поддерживает.
JDBC определяет следующие стандартные уровни изоляции транзакций (соответствующие уровням, определенным в стандарте SQL). Они представлены как статические константы в интерфейсе
:
1.
(Уровень 0):
Транзакции не поддерживаются. Этот уровень обычно указывает, что драйвер или СУБД не поддерживает транзакции. Его использование не рекомендуется.
2.
(Уровень 1 - "Грязное чтение"):
Разрешены:
"Грязное чтение" (Dirty Reads): Транзакция A может читать данные, которые были изменены транзакцией B, но еще не зафиксированы (не committed) транзакцией B. Если транзакция B затем откатывается
(
), то транзакция A прочитала "грязные", недействительные данные.
"Неповторяющееся чтение" (Non-Repeatable Reads): (См. ниже) "Фантомное чтение" (Phantom Reads): (См. ниже)
Предотвращает: Ничего из перечисленных проблем параллелизма.
Использование: Редко используется из-за высокого риска чтения некорректных данных. Может быть оправдан в ситуациях, где приблизительные данные допустимы, а производительность критична.
3.
(Уровень 2 - "Чтение зафиксированных данных"):
Разрешены:
"Неповторяющееся чтение" (Non-Repeatable Reads): Транзакция A
читает строку. Затем транзакция B изменяет или удаляет эту строку и фиксирует изменения. Если транзакция A снова читает ту же строку, она увидит измененные данные или обнаружит, что строка удалена. Таким образом, повторное чтение той же строки в рамках одной транзакции A может дать разные результаты.
"Фантомное чтение" (Phantom Reads): (См. ниже)
Предотвращает:
"Грязное чтение" (Dirty Reads): Транзакция может читать только те данные, которые были зафиксированы другими транзакциями.
Использование: Это уровень изоляции по умолчанию для многих популярных СУБД (например, PostgreSQL, SQL Server, Oracle). Обеспечивает хороший баланс между согласованностью данных и производительностью.
4.
(Уровень 3 - "Повторяемое чтение"):
Разрешены:
"Фантомное чтение" (Phantom Reads): Транзакция A выполняет запрос с определенным условием (например, 
). Затем транзакция B вставляет новые строки, удовлетворяющие этому условию, и фиксирует изменения. Если транзакция A повторяет свой запрос, она увидит новые "фантомные" строки, которые не существовали при первом выполнении запроса.
Предотвращает:
"Грязное чтение" (Dirty Reads).
"Неповторяющееся чтение" (Non-Repeatable Reads): Если транзакция читает строку, она будет видеть те же данные в этой строке при повторных чтениях, даже если другие транзакции изменяют и фиксируют эту строку. СУБД обычно достигают этого с помощью блокировок строк или версионирования (MVCC).
Использование: Используется, когда важно, чтобы данные, прочитанные в начале транзакции, оставались неизменными на протяжении всей транзакции. Уровень по умолчанию для MySQL (с InnoDB).
5.
(Уровень 4 - "Сериализуемый"):
Разрешены: Никакие из перечисленных проблем параллелизма.
Предотвращает:
"Грязное чтение" (Dirty Reads).
"Неповторяющееся чтение" (Non-Repeatable Reads).
"Фантомное чтение" (Phantom Reads).
Поведение: Этот уровень обеспечивает наивысшую степень изоляции. Транзакции выполняются так, как будто они выполняются последовательно (одна за другой), даже если на самом деле они могут выполняться параллельно. СУБД обычно достигают этого с помощью строгих блокировок (например, блокировок диапазона ключей или предикатных блокировок) или других техник.
Использование: Используется, когда требуется максимальная согласованность данных и любая аномалия параллелизма недопустима. Однако это может значительно снизить производительность и увеличить вероятность взаимных блокировок из-за более агрессивного использования блокировок.
Как установить уровень изоляции в JDBC:
Используется метод
интерфейса
:
Важные моменты:
Поддержка СУБД: Не все СУБД поддерживают все уровни изоляции, или их реализация может иметь особенности. Если запрошенный уровень не поддерживается, драйвер может выбрать следующий более строгий поддерживаемый уровень или выбросить
.
Уровень по умолчанию: Каждая СУБД имеет свой уровень изоляции по умолчанию. Его можно узнать через
до явной установки.
Влияние на производительность и параллелизм: Более высокие (строгие)
уровни изоляции обеспечивают лучшую согласованность данных, но обычно снижают степень параллелизма и могут негативно сказаться на производительности из-за более активного использования блокировок.
Когда устанавливать: Уровень изоляции обычно устанавливается один раз после получения соединения и до начала каких-либо транзакционных операций (если
выключен). Изменение уровня изоляции во время активной транзакции может привести к ее немедленной фиксации (зависит от СУБД и драйвера).
Выбор правильного уровня изоляции — это компромисс между требованиями к согласованности данных, производительностью и степенью параллелизма приложения.
83. При помощи чего формируются запросы к базе данных?
В JDBC запросы к базе данных формируются и выполняются с использованием следующих основных интерфейсов:
1.
:
Назначение: Используется для выполнения статических SQL-запросов
(запросов, которые не содержат параметров, подставляемых во время выполнения).
Формирование запроса: SQL-запрос передается в виде строки (
) непосредственно в методы выполнения
.
Методы выполнения:
: Для
-запросов.
: Для
,
,
или DDL-
команд.
: Для любого типа SQL-запроса.
Пример:
Недостатки:
Уязвим для SQL-инъекций, если SQL-запрос формируется путем конкатенации строк с пользовательским вводом.
Менее производителен для повторяющихся запросов, так как СУБД должна каждый раз парсить и оптимизировать SQL-строку.
2.
:
Назначение: Используется для выполнения параметризованных (предкомпилированных) SQL-запросов. Это предпочтительный способ для большинства SQL-операций.
Формирование запроса: SQL-запрос содержит плейсхолдеры (placeholders),
обычно обозначаемые знаком вопроса (
), вместо конкретных значений. Сам SQL-запрос передается при создании объекта
.
Установка параметров: Значения для плейсхолдеров устанавливаются с помощью методов
(например,
,
,
) перед выполнением запроса. Параметры нумеруются, начиная с 1.
Методы выполнения:
: Для
-запросов (параметры уже установлены).
: Для
,
,
(параметры уже установлены).
: Для любого типа запроса.
Пример:
Преимущества:
Защита от SQL-инъекций: Параметры передаются отдельно от SQL-кода и обрабатываются драйвером как данные, а не как исполняемый SQL. Производительность: СУБД может предкомпилировать запрос один раз и затем эффективно выполнять его многократно с разными параметрами. Читаемость: Часто более читаемо, чем конкатенация строк для формирования SQL.
3. |
|
|
: |
|
|
|
|
Назначение: Используется для вызова хранимых процедур и функций базы |
|||||||
данных. |
|
|
|
|
|
|
|
Формирование запроса: SQL-строка для вызова процедуры использует |
|||||||
специальный синтаксис, обычно |
|
|
|
или |
|||
|
|
. Плейсхолдеры используются для входных ( |
), выходных |
||||
( |
) и входных/выходных ( |
) параметров. |
|
|
|||
Установка параметров: Аналогично |
|
, используются методы |
|||||
|
для |
и |
параметров. |
|
|
|
|
Регистрация |
параметров: Для |
и |
параметров необходимо |
||||
зарегистрировать их тип с помощью |
|
|
|
||||
|
|
|
. |
|
|
|
|
Получение |
параметров: После выполнения процедуры значения |
||||||
параметров извлекаются с помощью методов |
. |
|
|||||
Методы выполнения: Обычно |
|
или |
|
. Если |
|||
процедура возвращает |
|
, его можно получить через |
. |
||||
Пример (упрощенный, синтаксис вызова процедуры зависит от СУБД):
В итоге:
: для очень простых, одноразовых, непараметризованных запросов (использовать с осторожностью из-за SQL-инъекций).
: для большинства SQL-запросов, особенно если они выполняются многократно или содержат параметры. Это стандартный и
рекомендуемый выбор.
: для вызова хранимых процедур и функций.
Все эти интерфейсы предоставляют методы для формирования и выполнения SQLзапросов к базе данных через установленное JDBC
.
84. Чем отличается Statement от PreparedStatement?
и
— это два интерфейса в JDBC, используемые для выполнения SQL-запросов, но они имеют существенные различия в способе работы, производительности и безопасности.
является
предпочтительным выбором в большинстве случаев.
Вот ключевые отличия:
Характеристика |
|
|
|
|
|
Тип SQL-запроса |
Статический SQL-запрос (без |
Динамический SQL-запрос |
|
параметров, передаваемых |
параметрами (плейсхолдер |
|
отдельно). |
|
|
|
|
Компиляция SQL |
SQL-запрос компилируется |
SQL-запрос предваритель |
|
(парсится и оптимизируется) |
компилируется базой данн |
|
базой данных каждый раз при |
раз (при создании |
|
выполнении. |
или первом выполнении). З |
|
|
может многократно выполн |
|
|
разными параметрами. |
|
|
|
Характеристика |
|
|
|
|
|
|
|
Производительность |
Обычно менее |
Обычно более производит |
|
|
производителен для |
запросов, выполняемых мн |
|
|
запросов, выполняемых |
так как план выполнения за |
|
|
многократно, из-за повторной |
кешируется СУБД. |
|
|
компиляции. |
|
|
|
|
|
|
Безопасность (SQL- |
Уязвим для SQL-инъекций, |
Защищает от SQL-инъекц |
|
инъекции) |
если SQL-строка формируется |
правильном использовании |
|
|
путем конкатенации с |
параметры передаются отд |
|
|
непроверенным |
SQL-кода и обрабатываютс |
|
|
пользовательским вводом. |
данные, а не как часть испо |
|
|
|
SQL. |
|
|
|
|
|
Передача |
Параметры (если есть) |
Параметры устанавливают |
|
параметров |
должны быть встроены |
помощью методов |
|
|
непосредственно в SQL-строку |
(например, |
, |
|
(например, через |
после создания |
|
|
конкатенацию). |
|
|
|
|
|
|
Читаемость кода |
Формирование SQL путем |
Использование плейсхолде |
|
|
конкатенации может сделать |
методов |
часто де |
|
код менее читаемым и |
более чистым и понятным. |
|
|
подверженным ошибкам. |
|
|
|
|
|
|
Работа с |
Менее удобен для работы с |
Более удобен для работы с |
|
бинарными |
большими бинарными |
бинарными данными (напр |
|
данными |
данными (BLOB/CLOB). |
|
, |
|
|
|
|
Создание |
|
|
|
|
|
|
|
Выполнение |
, |
, |
|
|
|
(без SQL-строки в аргумент |
|
|
|
|
|
Подробнее о ключевых отличиях:
1. Компиляция и Производительность:
: Каждый раз, когда вы вызываете 
, СУБД должна заново проанализировать (разобрать) SQL-строку, проверить синтаксис, оптимизировать запрос и затем выполнить его. Если этот запрос выполняется много раз в цикле, это приводит к значительным накладным расходам.
: Когда вы создаете 
, СУБД (или драйвер) может предкомпилировать этот SQL-шаблон. При последующих вызовах
СУБД использует уже готовый план выполнения, просто подставляя новые значения параметров. Это значительно быстрее для повторяющихся запросов.
2. Безопасность (SQL-инъекции):

(уязвимый пример):

(безопасный пример):
обрабатывает переданные значения параметров как литералы данных, а не как исполняемый SQL-код, что исключает возможность внедрения вредоносных SQL-команд.
Когда
может быть приемлем (редко):
Для выполнения SQL-запросов, которые выполняются только один раз за время жизни приложения.
Для DDL-операций (Data Definition Language, например,
, 
), которые обычно не содержат пользовательских параметров и выполняются редко.
Если SQL-запрос генерируется полностью программно без использования какоголибо внешнего ввода, и вы уверены в его безопасности.
Вывод:
Всегда отдавайте предпочтение
перед
, особенно если:
SQL-запрос содержит параметры (значения, которые меняются). SQL-запрос выполняется многократно.
Параметры запроса формируются на основе пользовательского ввода или других внешних данных (критично для безопасности).
