понедельник, 9 июня 2014 г.

Spring Data JPA

Этот модуль фреймворка Spring помогает избежать шаблонного кода работы с ЭнтитиМенеджера.

И так Spring Data JPA:
- A wrapper for JPA
  - Need to know JPA before you can use Spring Data JPA
- Replaces our Repository Tier
- Extremely powerful and eliminates boiler plate code
- Can be extended for additional functionality


Важный момент, что EM имеет два метода которые по сути делают разные вещи:
persist - сохраняет новую запись в таблицу;
merge - обновляет существующую.

Обычно мы в своем классе-репозитории реализуем метод save, который в зависимости от ситуации использует первый или второй метод.


public Goal save(Goal goal) {
  if(goal.getId() == null) {
    em.persist(goal);
    em.flush();
  } else {
    goal = em.merge(goal);
  }

  return goal;
}
Стоит обратить внимание, что когда используется merge, не вызывается после него flash, это потому что реализация merge обеспечивает мгновенное попадание изменений в базу.

Maven:
- Need to add the spring-data-jpa jar
- spring-data-jpa contains an incompatible transitive dependency
  - Exclude spring-aop

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
  <version>1.3.0.RELEASE</version>
  <exclusions>
      <exclusion>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
      </exclusion>
  </exclusions>
</dependency>
To aid in configuring there is a JPA Namespace
  xmlns:jpa="http://www.springframework.org/schema/data/jpa"

  http://www.springframework.org/schema/data/jpa
   http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd

  <jpa:repositories base-package="com.domain.repository"/>

А теперь посмотрим, что нам все это позволит сэкономить в написании кода.

Теперь нам не нужны реализации интерфейсов репозиториев - все стандартные методы определены в прокси, который нацепится на указанный как репозиторий интерфейс, для IDE мы расширяет библиотечный интерфейс, чтобы видеть в подсказках нужные нам методы при работе с интанциями репозитория, нестандартные методы мы опишем с помощью @Queries( org.springframework.data.jpa.repository.Query), которые по сути как javax.persistence.NamedQueries, только вот живут в более подходящих местах и выполнять не нам их нужно, а выполнит это прокси spring.

package com.domain.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.domain.model.Goal;
import com.domain.model.GoalReport;

@Repository("GoalRepository")
public interface GoalRepository extends JpaRepository {

  @Query("Select new com.pluralsight.model.GoalReport(g.minutes, e.minutes, e.activity)" +
      "from Goal g, Exercise e where g.id = e.goal.id")
  List findAllGoalReports();
}

Комментариев нет:

Отправить комментарий