Подтвердить что ты не робот

Смутно о Spring -Data DDD файле репозитория

Я не так много знаю о шаблоне репозитория DDD, но реализация в Spring путают меня.

public interface PersonRepository extends JpaRepository<Person, Long> { … }

Поскольку интерфейс расширяет JpaRepository (или MongoDBRepository...), если вы переходите от одного db к другому, вам также нужно изменить интерфейс.

Для меня интерфейс есть, чтобы обеспечить некоторую абстракцию, но здесь она не так абстрактна...

Знаете ли вы, почему Spring -Дата работает так?

4b9b3361

Ответ 1

Вы правы, интерфейс - это абстракция о чем-то, что работает равным для всех реализующих классов, с внешней точки зрения.

И это именно то, что происходит здесь:

  • JpaRepository - это общее представление обо всех ваших репозиториях JPA (для всех разных сущностей), в то время как MongoDBRepository одинаково для всех объектов MongoDB.
  • Но JpaRepository и MongoDBRepository не имеют ничего общего, кроме тех вещей, которые определены там, в общих супер интерфейсах:

    • org.springframework.data.repository.PagingAndSortingRepository
    • org.springframework.data.repository.Repository

Так что для меня это выглядит нормально.

Если вы используете классы, которые реализуют ваш репозиторий, используйте PagingAndSortingRepository или репозиторий, если вы хотите перейти от реализации JPA к реализации на основе документа (извините, но я не могу представить такой вариант использования - в любом случае). И, конечно, ваша реализация Репозитория должна реализовать правильный интерфейс (JpaRepository, MongoDBRepository) в зависимости от того, что это такое.

Ответ 2

Обоснование этого довольно четко указано в этом сообщении в блоге http://blog.springsource.com/2011/02/10/getting-started-with-spring-data-jpa/.

Определение этого интерфейса служит двум целям: во-первых, расширяя JpaRepository, мы получаем кучу общих методов CRUD в наш тип, который позволяет экономить учетные записи, удаляя их и т.д. Во-вторых, это позволит инфраструктуре репозитория Spring Data JPA сканировать путь к классам для этого интерфейса и создать для него Spring bean.

Если вы не доверяете источникам, близким к источнику (каламбур), неплохо было бы также прочитать этот пост http://www.brucephillips.name/blog/index.cfm/2011/3/25/Using-Spring-Data-JPA-To-Reduced-Data-Access-Coding. p >

То, что мне не нужно было кодировать, - это реализация интерфейса PersonRepository. Spring создаст реализацию этого интерфейса и сделает доступным PersonRepository bean для автоматического подключения к моему классу службы. PersonRepository bean будет иметь все стандартные CRUD-методы (которые будут транзакционными) и возвращать объекты Person или коллекцию объектов Person. Поэтому, используя Spring Data JPA, я сохранил свой собственный класс реализации.

Ответ 3

До M2 из Spring Data мы потребовали, чтобы пользователи расширили JpaRepository по следующим причинам:

  • Инфраструктура сканирования класса маршрутизировала только интерфейсы, расширяющие этот интерфейс, так как можно было бы использовать Spring Data JPA и Spring Data Mongo параллельно, и оба они указывали на тот же пакет, что было бы непонятно, создайте прокси-сервер. Однако с RC1 мы просто оставляем эту нагрузку разработчику, поскольку считаем это довольно экзотическим случаем и преимущество использования Repository, CrudRepository или подобных перераспределений усилий, которые вы должны предпринять в только что описанном угловом случае. Вы можете использовать элементы exclude и include в пространстве имен, чтобы получить более тонкий контроль над этим.
  • До M2 мы применяли транзакцию к методам CRUD, обновляя методы CRUD и аннотируя их с помощью @Transactional. Это решение, в свою очередь, было обусловлено алгоритмом AnnotationTransactionAttributeSource, используемым для поиска конфигурации транзакции. Поскольку мы хотели предоставить пользователю возможность перенастроить транзакции, просто обновив CRUD-метод в конкретном интерфейсе репозитория и применив к нему @Transactional. Для RC1 мы решили реализовать пользовательский TransactionAttributeSource, чтобы иметь возможность переместить аннотации обратно в реализацию CRUD репозитория.

Короче говоря, вот что это сводится к:

По состоянию на RC1 нет необходимости расширять интерфейс хранилища конкретного хранилища, кроме, который вы хотите...

  • Используйте List доступ к findAll(…) вместо Iterable на основе более основных интерфейсов репозитория (хотя вы могли бы просто повторно использовать соответствующие методы в общем базовом интерфейсе, чтобы возвращать List)
  • Вы хотите использовать специфичные для JPA методы, такие как saveAndFlush(…) и т.д.

Как правило, вы гораздо более гибко относитесь к воздействию методов CRUD с RC1, поскольку вы даже можете расширить интерфейс маркера Repository и выборочно добавить методы CRUD, которые вы хотите просмотреть. Поскольку реализация поддержки все еще реализует все методы PagingAndSortingRepository, мы все равно можем маршрутизировать вызовы к экземпляру:

public interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

  List<T> findAll();

  T findOne(ID id);
}

public interface UserRepository extends MyBaseRepository<User, Long> {

  List<T> findByUsername(String username);
}

В этом примере мы определяем MyBaseRepository только для отображения findAll() и findOne(…) (который будет перенаправлен в экземпляр, реализующий методы CRUD), и конкретный репозиторий, добавляющий метод поиска к двум CRUD-тегам.

Подробнее об этой теме читайте в справочной документации .