Java + MS SQL Server через JDBC
Мы научились работать с базой данных «Библиотека» вручную — через программу SQL Server Management Studio (SSMS, программа для работы с MS SQL Server). Но настоящие приложения работают с базой программно. Именно этим займёмся сегодня.
PreparedStatement.
План практики
Сегодня мы пройдём путь от «что такое JDBC» до работающего Java-приложения.
- 1 Что такое JDBC и зачем нужен драйвер
- 2 Что нужно для подключения
- 3 Скачиваем драйвер mssql-jdbc
- 4 Подключаем драйвер к проекту
- 5 Первое подключение к базе
- 6 Чтение данных: Statement + ResultSet
- 7 Добавление данных: PreparedStatement
- 8 Почему PreparedStatement безопаснее
- 9 Собираем консольное приложение
- 10 Обработка ошибок и типичные проблемы
- 11 Практика и домашнее задание
Что такое JDBC?
JDBC (Java Database Connectivity, «связь Java с базами данных») — это стандартный интерфейс Java для работы с реляционными базами данных.
- JDBC — это набор классов и интерфейсов в пакете
java.sql. Они входят в стандартную поставку JDK (Java Development Kit, комплект разработчика Java). - Драйвер — это отдельная библиотека, которая «переводит» команды JDBC на язык конкретной базы данных.
- Для MS SQL Server драйвер называется
mssql-jdbc. Его нужно скачать отдельно.
Что нужно для подключения
Чтобы подключиться к MS SQL Server из Java, нужно четыре вещи.
Комплект разработчика Java (версия 8 или новее).
Запущенный сервер с базой
LibraryDB (из Практики 1).JAR-файл с драйвером. JAR — это Java Archive, архив Java-классов.
IntelliJ IDEA, Eclipse или VS Code — где вы пишете код.
Скачиваем драйвер mssql-jdbc
Драйвер mssql-jdbc — это JAR-файл, который нужно добавить в проект. Есть два способа: через систему сборки Maven (популярный инструмент сборки Java-проектов) или вручную.
Способ 1. Maven (если проект на Maven)
Добавьте в файл pom.xml:
Maven сам скачает драйвер и все его зависимости.
Способ 2. Вручную
- Скачайте JAR-файл с официального сайта Microsoft.
- Положите его в папку
lib/проекта. - В IDE добавьте его в classpath: «Project Structure → Libraries → Add JAR».
Структура Java-проекта
Создадим стандартную структуру Java-проекта.
- src/ — исходный код.
- ru/gadget59/library — пакет проекта (соглашение об именах — домен в обратном порядке + назначение).
- lib/ — сторонние библиотеки (JAR-файлы).
ru.gadget59.library — это пространство имён. Внутри него лежат наши классы. Имя пакета совпадает со структурой папок — это требование Java.Строка подключения (Connection URL)
Чтобы Java нашла базу данных, ей нужна строка подключения (connection URL, Uniform Resource Locator — универсальный адрес ресурса).
Первое подключение
Напишем минимальную программу, которая просто проверяет, что подключение работает.
lib/.Что такое Connection
Connection (соединение) — это объект, который представляет активное подключение к базе данных.
- Один Connection = одно соединение с базой.
- Через него отправляются SQL-запросы.
- В конце работы Connection нужно закрыть.
try (Connection conn = ...). Это специальный синтаксис Java — «try-with-resources», который автоматически закрывает соединение, когда мы выходим из блока. Мы разбирали его в лекции про исключения.Чтение данных: Statement и ResultSet
Прочитать данные из базы можно через Statement (запрос) и ResultSet (результат).
Books, отсортированные по году.Как работает ResultSet
ResultSet (набор результатов) — это таблица с результатами SELECT-запроса.
rs.next()— перейти на следующую строку. Возвращаетfalse, когда строки закончились.rs.getString("Title")— прочитать столбец «Title» из текущей строки.rs.getInt("Year")— прочитать целочисленный столбец.- Можно читать и по индексу:
rs.getString(1)— первый столбец. Но по имени надёжнее.
next().Добавление данных: INSERT
Для добавления данных используется метод executeUpdate и команда INSERT.
Проблема: SQL-инъекция
SQL-инъекция — это атака, при которой злоумышленник подставляет в SQL-запрос хитрую строку и получает доступ к данным, к которым не должен.
Пример уязвимого кода
Что может ввести злоумышленник
Тогда SQL-запрос станет таким:
'1'='1' всегда истинно. Запрос вернёт всех читателей, а не одного. Так хакеры крадут пароли, банковские данные и личную информацию.Решение: PreparedStatement
PreparedStatement (подготовленный запрос) — это способ отправки SQL-запроса, при котором значения передаются отдельно от команд SQL.
' OR '1'='1, это будет воспринято как обычный текст, а не как команда SQL.INSERT через PreparedStatement
PreparedStatement используется не только для SELECT, но и для INSERT, UPDATE, DELETE.
? — это «дырка» в запросе, куда будет подставлено значение.setString(1, ...) — подставить строку в первую дырку.setInt(2, ...) — подставить число во вторую.Нумерация начинается с 1, а не с 0!
SELECT с условием через PreparedStatement
Найдём все книги конкретного автора, подставив имя через параметр.
Собираем всё вместе: DatabaseHelper
Хорошая практика — вынести подключение и общие методы в отдельный класс.
DatabaseHelper.getConnection() — и получить соединение. Это удобно и безопасно.Метод «показать все книги»
Добавим в DatabaseHelper метод, который выводит все книги с авторами.
System.out.printf — это форматированный вывод. %-30s означает «строка, выровненная по левому краю, шириной 30 символов».Метод «добавить читателя»
Добавим метод, который безопасно вставляет нового читателя.
DatabaseHelper.addReader("Алексей", "alex@mail.ru", "2026-10-25"), и читатель появится в базе.Метод «активные читатели»
Найдём читателей, которые взяли больше одной книги.
Statement, потому что в запросе нет пользовательских значений. Для запросов с параметрами лучше PreparedStatement.Главный класс
Соберём всё вместе в главном классе.
Правила безопасного кода с JDBC
Запомните эти правила — они уберегут вас от большинства проблем.
- Всегда используйте PreparedStatement, если в запросе есть значения от пользователя. Никаких склеек строк.
- Всегда закрывайте Connection, Statement и ResultSet через try-with-resources.
- Не храните пароли в коде. Пароль к базе — только в файле конфигурации.
- Не выводите данные в консоль в продакшене. Используйте логгер.
- Обрабатывайте SQLException. Пользователь должен видеть понятное сообщение об ошибке.
- Не открывайте лишних соединений. Если можно переиспользовать — переиспользуйте.
Типичные ошибки
Драйвер не подключён. Проверьте Maven или папку
lib/.Проблема с правами. Для локальной разработки используйте Windows Authentication.
SQL Server не принимает TCP-подключения. Проверьте настройки в SQL Server Configuration Manager.
Таблица не найдена. Проверьте, что вы выполнили
USE LibraryDB.Проблема с кодировкой. Используйте
NVARCHAR и N перед русскими строками.Соединение уже закрыто. Проверьте, что вы не используете его после закрытия.
Практический результат
Вот что вы получите, если выполните все шаги.
Самостоятельные задания
Попробуйте дописать эти методы самостоятельно.
- Метод
showAllReaders()— вывести всех читателей с email и датой регистрации. - Метод
showBooksByAuthor(String authorName)— книги конкретного автора черезPreparedStatement. - Метод
showUnreturnedBooks()— книги, которые ещё не вернули (черезIS NULL). - Метод
addLoan(int bookId, int readerId)— оформить выдачу книги читателю. - Метод
returnLoan(int loanId)— отметить книгу возвращённой (установитьReturnDate). - Метод
showTopReaders()— топ-3 читателя по количеству взятых книг.
UPDATE используйте executeUpdate. Для SELECT — executeQuery.Итоги практики
Подведём итоги. Вот что вы теперь умеете.
- ✅ JDBC — стандартный интерфейс Java для работы с базами данных.
- ✅ Драйвер mssql-jdbc — библиотека, связывающая Java с MS SQL Server.
- ✅ Connection — объект подключения к базе.
- ✅ Statement — простой запрос без параметров.
- ✅ PreparedStatement — безопасный запрос с параметрами.
- ✅ ResultSet — результат SELECT-запроса.
- ✅ executeQuery — для SELECT, executeUpdate — для INSERT, UPDATE, DELETE.
- ✅ SQL-инъекция — угроза, от которой защищает
PreparedStatement. - ✅ try-with-resources — автоматическое закрытие ресурсов.
Домашнее задание
Задания для самостоятельной работы. Первые три обязательны, остальные — для оценки «отлично».
- Реализуйте все методы из слайда «Самостоятельные задания».
- Добавьте обработку ошибок: пользователь не должен видеть стек-трейс. Только понятное сообщение.
- Добавьте метод
findReaderByEmail(String email)черезPreparedStatement. - Создайте консольное меню: пользователь выбирает действие (показать книги, добавить читателя, выдать книгу и т.д.).
- Добавьте логирование SQL-запросов в консоль (какой запрос выполняется).
- Попробуйте SQL-инъекцию на своём коде и убедитесь, что
PreparedStatementеё блокирует.
Спасибо за работу!
🔌
Java умеет говорить с базой данных!
Вы прошли весь путь: от пустого окна SSMS до Java-приложения, которое читает и пишет данные. Это полноценный backend-навык.