Hello, Spring Data JPA

Мечта официантки — чтобы клиенты обедали у себя дома, а чаевые присылали ей по почте. Я думаю разработчики тоже не отказались бы, чтобы программы писали себя сами, хотя бы малую часть. Именно это делает Data , который является частью большего проекта, Spring Data.

Spring Data JPA позволяет заменить ручную реализацию JPA запросов к базе данных на её декларативное объявление. Говоря более предметно, Spring Data JPA позволяет заменить классы, подобные тому, что показан ниже, на однострочный интерфейс.

Подготовка

Помимо обычных реализации JPA и, собственно, Spring, необходимо добавить в maven проект артефакт Spring Data JPA:

Настройка JPA и Spring Context

Описания сущностей, с которыми мы будем работать, я взял из примера JPA entity mapping, и не хочу на них подробно останавливаться сейчас. Конфигурация JPA достаточно проста. Поскольку в качестве реализации JPA я использую Hibernate, то всё сводится к включению создания таблиц и настройке соединения с базой. Напоминаю, что конфигурация JPA по соглашению размещается в файле /META-INF/persistence.xml

Главное, что нам понадобится из настроек JPA, это имя persistence unit, которое передаётся в конфигурацию Spring. В этот раз мы будем настраивать Spring context используя Java config

Контекст будет маленький, только создание JPA бина и менеджера транзакций. Самое интересное делает аннотация @EnableJpaRepositories. Эта аннотация включает поддержку Spring Data JPA и автогенерацию кода для доступа к данным. Наличие этой аннотации подразумевает, что в Spring context будет два бина, один с именем entityManagerFactory, другой с именем transactionManager.  Думаю типы этих бинов понятны из названия 🙂 При желании имена бинов можно задать явно в параметрах аннотации.

Уровень DAO

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

И нет, я не забыл написать реализацию интерфейса. За меня это сделает Spring Data JPA.

Интерфейс CrudRepository определяет следующие методы:

  • count() — возвращает число сущностей этого класса в базе
  • delete(id)/delete(Iterable) — удаляет сущность с заданным(и) id
  • exists(id) — проверяет, есть ли в базе сущность с заданным id
  • findAll() — возвращает все сущности этого класса
  • find(id) — возвращает сущность с заданным id (или null, если таковой нет)
  • save(entity)/save(Iterable) — сохраняет сущность (сущности) в базу

Таким образом, в каждом интерфейсе, заданном выше, мы автоматически получаем реализации вышеописанных методов. Совершенно бесплатно, то есть даром.

Но что если этих методов недостаточно? Spring Data JPA позволяет декларативно задавать описания запросов прямо в интерфейсе:

Метод findByFirstName() автоматически будет сгенерирован и будет делать ровно то, что говорит его название — искать по полю firstName в сущности Person.

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

Просто добавляете зависимость от вашего интерфейса в класс и используете, как если бы вы сами его писали.

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