Spring ORM и Hibernate

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

Подготовка

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

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <javaee.version>7.0</javaee.version>
  <lombok.version>1.16.12</lombok.version>
  <org.springframework.version>4.3.4.RELEASE</org.springframework.version>
  <hibernate.version>5.2.5.Final</hibernate.version>
  <h2.version>1.4.190</h2.version>
  <junit.version>4.12</junit.version>
  <hamcrest.version>1.3</hamcrest.version>
  <easymock.version>3.3.1</easymock.version>
</properties>


<dependencies>
  <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
  </dependency>


  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
  </dependency>


  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${org.springframework.version}</version>
  </dependency>


  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>${org.springframework.version}</version>
  </dependency>


  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${org.springframework.version}</version>
    <scope>test</scope>
  </dependency>


  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>${h2.version}</version>
  </dependency>


  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>${hibernate.version}</version>
  </dependency>


  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
  </dependency>


  <dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>${hamcrest.version}</version>
    <scope>test</scope>
  </dependency>


  <dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>${easymock.version}</version>
  </dependency>
</dependencies>

Настройка Hibernate

Конфигурация Hibernate традиционно располагается в файле hibernate.cfg.xml В моём примере я использую H2 в качестве базы данных:

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
    <property name="hibernate.connection.url">jdbc:h2:mem:test</property>
    <mapping class="ru.easyjava.spring.data.hibernate.entity.Greeter"/>
  </session-factory>
</hibernate-configuration>

Можно использовать любые базы данных и пулы соединений.

Настройка Spring

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

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
   <property name="configLocation" value="hibernate.cfg.xml"/>
</bean>

Свойство configLocation указывает на имя и расположение файла конфигурации Hibernate.

Вместо настройки базы в конфигурации hibernate можно использовать Spring для разделения настроек соединения, пула соединений и Hibernate:

<beans>
  <bean id="h2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="dbc:h2:mem:test"/>
  </bean>


  <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="h2"/>
    <property name="mappingResources">
      <list>
        <value>greeter.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
        <value>
          hibernate.dialect=org.hibernate.dialect.H2Dialect
        </value>
      </property>
  </bean>


</beans>

В примере выше создаётся пул соединений DBCP к базе H2, который передаётся  в конфигурацию Hibernate.

Схема данных

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

@Entity
public class Greeter {
    @Id
    @GeneratedValue
    @Getter
    @Setter
    private Integer id;


    @Getter
    @Setter
    private String greeting;


    @Getter
    @Setter
    private String target;
}

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

Уровень DAO

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

public interface GreeterDao {
  void addGreet(Greeter g);


  List<Greeter> getGreetings();
}

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

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

public interface GreeterService {
    String greet();
}

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

public static void main(final String[] args) {
  ApplicationContext context =
     new ClassPathXmlApplicationContext("/applicationContext.xml");
  GreeterService greeterService = context.getBean(GreeterService.class);
  GreeterDao dao = context.getBean(GreeterDao.class);


  Greeter greeter = new Greeter();
  greeter.setGreeting("Hello");
  greeter.setTarget("World");


  dao.addGreet(greeter);


  System.out.println(greeterService.greet());


  System.exit(0);
}
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *