Hello, Spring JDBC!

, как всегда, упрощает использование сторонних API и делает жизнь разработчика проще. Поддержка в framework берёт на себя часть реализации обязательного кода для работы с JDBC: поддержку соединений, транзакции, выполнение запросов, закрытие ресурсов и т.д.

Подготовка

Нам понадобится пустой maven проект с Spring, Spring JDBC, H2 и библиотеками тестирования:

Соединение

Я использую XML конфигурацию для настройки параметров соединения:

Настройка Spring JDBC в общем случае требует двух действий — настройку data source, то есть конкретного соединения с базой, и связывание его с JdbcTemplate, классом, который и реализует интерфейс к Spring JDBC.

Выполнение запросов

Чтоб к базе обращаться, в ней надо создать какую-нибудь таблицу:

Bean jdbcTemplate просто добавляется в сервис, используя стандартные механизмы Spring. Метод execute() выполняет любой запрос к базе и не возвращает ничего. В случае ошибки метод кидает DataAccessException.

Запросы

execute()  — очень удобный метод, если надо создать таблицу. Но метод, который не возвращает ничего, малополезен при работе с данными, да и связывание параметров гораздо удобнее формирования запросов склеиванием строк.

В Spring JDBC есть два основных семейства методов: update() и query*(), которые служат для выполнения запросов изменяющих данные и возвращающих данные.

Метод update(), из примера выше, принимает запрос и параметры запроса. Метод queryForList() возвращает список key-value объектов. Каждый элемент списка соответствует одной строке в result set, который возвращает запрос, а Map содержит значения столбцов строки, ключами к которым являются имена столбцов.

Уровень DAO

Хорошим тоном разработки является разделение кода, который работает непосредственно с базами данных (уровень DAO), от кода, который обрабатывает данные (уровень сервисов). Это позволяет абстрагировать сервисы от конкретной реализации DAO и, при необходимости, менять эти реализации без изменения кода сервисов. В Spring даже предусмотрены отдельные аннотации, которые имеют в настоящий момент одинаковый эффект, но позволяют разработчику сразу понять, что делает тот или иной класс. Так  GreeterServiceimpl имеет аннотацию @Service, а GreeterDaoImpl аннотацию @Repository.

Обратите внимание, что тест сервиса проверяет только сервис, заменяя GreeterDao его подделкой. В то время как тесты DAO являются интеграционными и работают непосредственно с базой.

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

Код примера доступен на github.

P.S. DAO — Data Access Object, стандартный шаблон проектирования, описывающий объект, который предоставляет интерфейс к какому-либо типу базы данных или механизму хранения.