Spring ORM и JPA

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

Подготовка

Нам понадобится пустой maven проект с Spring, Spring ORM, H2, Hibernate в качестве реализации JPA и библиотеками тестирования:

Настройка JPA

Конфигурация JPA располагается в файле META-INF/persistence.xml В моём примере я использую Hibernate в качестве реализации JPA и встраиваемую базу H2 в качестве базы данных.

Разумеется, в настройках Hibernate как JPA реализации можно использовать любые базы данных и пулы соединений.

Настройка Spring

Для включения поддержки JPA в Spring необходимо добавить в контекст особый бин. Можно сделать это программно, а можно с использованием xml конфигурации:

Свойство persistensUnitName связывает конкретный бин с конкретным persistence unit, сконфигурированным в persistence.xml

Схема данных

ORM отображает объектную модель данных на реляционную модель данных. Чтобы не загораживать пример, используем как можно более простую модель:

Аннотация @Entity говорит JPA, что это класс сущности, а @Getter и @Setter генерируют код для доступа к полям.

Уровень DAO

Хорошим тоном разработки является разделение кода, который работает непосредственно с базами данных (уровень DAO), от кода, который обрабатывает данные (уровень сервисов). Это позволяет абстрагировать сервисы от конкретной реализации DAO и, при необходимости, менять эти реализации без изменения кода сервисов.

Ключевой частью нашего DAO класса является объект EntityManagerFactory, который Spring самостоятельно внедряет в класс, увидев аннотацию @PersistenceUnit. Аннотация поддерживает параметр name, который позволяет указать, какой-же именно из persistence units надо внедрить, если их создано несколько.

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

Наконец, напишем сервис который будет использовать DAO, определённый выше, и делать что-нибудь с этими данными.

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

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

 

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