Рубрики
Без рубрики

Репозитории с несколькими модулями данных Spring

Узнайте несколько способов настройки нескольких модулей данных в приложении Spring.

Автор оригинала: baeldung.

1. введение

Иногда нам нужно подключиться к нескольким технологиям баз данных в одном приложении.

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

Давайте воспользуемся книжным магазином toy Spring Boot, чтобы изучить эту тему.

2. Необходимые зависимости

Во-первых, нам нужно добавить наши зависимости в pom.xml файл, чтобы мы могли использовать привязки spring-boot-starter-data-mongodb и spring-boot-starter-data-cassandra Spring Boot Data:


  org.springframework.boot
  spring-boot-starter-data-cassandra
  2.2.2.RELEASE


  org.springframework.boot
  spring-boot-starter-data-mongodb
  2.2.2.RELEASE

3. Настройка базы данных

Далее, нам нужно настроить фактические базы данных с помощью предварительно построенных Docker изображений Cassandra и Mongo :

$ docker run --name mongo-db -d -p 27017:27017 mongo:latest
$ docker run --name cassandra-db -d -p 9042:9042 cassandra:latest

Эти две команды автоматически загрузят последние образы докеров Cassandra и MongoDB и запустят фактические контейнеры.

Нам также необходимо перенаправить порты (с опцией -p ) из контейнеров в реальной среде операционной системы, чтобы наше приложение могло получить доступ к базам данных.

Мы должны создать структуру базы данных для Cassandra с помощью утилиты cqlsh . Создание пространства ключей не может быть выполнено автоматически с помощью Автоматической конфигурации данных Cassandra , поэтому нам нужно объявить его с помощью синтаксиса CQL .

Итак, сначала мы прикрепляемся к оболочке bash контейнера Cassandra:

$ docker exec -it cassandra-db /bin/bash
[email protected]:/# cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> CREATE KEYSPACE IF NOT exists baeldung 
WITH replication = {'class':'SimpleStrategy', 'replication_factor':1};
cqlsh> USE baeldung;
cqlsh> CREATE TABLE bookaudit(
   bookid VARCHAR,
   rentalrecno VARCHAR,
   loandate VARCHAR,
   loaner VARCHAR,
   primary key(bookid, rentalrecno)
);

В строках 6 и 9 мы создаем соответствующее пространство ключей и таблицу .

Мы могли бы пропустить создание таблицы и просто полагаться на spring-boot-starter-data-cassandra для инициализации схемы для нас, однако, поскольку мы хотим изучить конфигурации фреймворка по отдельности, это необходимый шаг.

По умолчанию Mongo не накладывает никакой проверки схемы, поэтому нет необходимости настраивать для нее что-либо еще .

Наконец, мы настраиваем соответствующую информацию о базах данных в нашем application.properties :

spring.data.cassandra.username=cassandra
spring.data.cassandra.password=cassandra
spring.data.cassandra.keyspaceName=baeldung
spring.data.cassandra.contactPoints=localhost
spring.data.cassandra.port=9042
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=baeldung

4. Механизмы обнаружения Хранилищ Данных

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

4.1. Расширение Интерфейсов Репозитория для конкретных Модулей

Первый механизм пытается определить, расширяет ли репозиторий тип репозитория, специфичный для модуля данных Spring:

public interface BookAuditRepository extends CassandraRepository {

}

Для целей нашего примера/| BookAudit.java содержит некоторую базовую структуру хранения для отслеживания пользователей, которые одолжили книгу:

public class BookAudit {
  private String bookId;
  private String rentalRecNo;
  private String loaner;
  private String loanDate;
 
  // standard getters and setters
}

То же самое относится и к определению репозитория, связанного с MongoDB:

public interface BookDocumentRepository extends MongoRepository {

}

В нем хранится содержание книги и некоторые соответствующие метаданные о ней:

public class BookDocument {
  private String bookId;
  private String bookName;
  private String bookAuthor;
  private String content;
  
  // standard getters and setters
}

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

@Test
public void givenBookAudit_whenPersistWithBookAuditRepository_thenSuccess() {

  // given
  BookAudit bookAudit = 
    new BookAudit("lorem", "ipsum", "Baeldung", "19:30/20.08.2017");

  // when
  bookAuditRepository.save(bookAudit);

  // then
  List result = bookAuditRepository.findAll();
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookAudit), is(true));
}

Вы можете заметить, что наши доменные классы-это простые объекты Java. В этой конкретной ситуации схема базы данных Cassandra должна быть создана извне с помощью CQL , как мы сделали в разделе 3.

4.2. Использование специфичных для модуля аннотаций на объектах Домена

Вторая стратегия определяет технологию сохранения, основанную на специфичных для модуля аннотациях на объектах домена.

Давайте расширим общий Crudrepository и теперь будем полагаться на аннотации управляемых объектов для обнаружения:

public interface BookAuditCrudRepository extends CrudRepository {

}
public interface BookDocumentCrudRepository extends CrudRepository {

}

В BookAudit.java теперь становится аннотированным с помощью Cassandra specific @Table и требует составного первичного ключа:

@Table
public class BookAudit {
  
  @PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED)
  private String bookId;
  @PrimaryKeyColumn
  private String rentalRecNo;
  private String loaner;
  private String loanDate;
  
  // standard getters and setters
}

Мы выбираем комбинацию бронирование и аренда Рено в качестве наших уникальных критериев, поскольку наше приложение просто регистрирует новую запись об аренде каждый раз, когда кто-то одалживает книгу.

Для BookDocument.java мы используем аннотацию @Document , которая специфична для MongoDB:

@Document
public class BookDocument {

  private String bookId;
  private String bookName;
  private String bookAuthor;
  private String content;
 
  // standard getters and setters
}

Запуск Book Document save с помощью CrudRepository по-прежнему успешен, но возвращаемый тип в строке 11 теперь является Итерируемым вместо List :

@Test
public void givenBookAudit_whenPersistWithBookDocumentCrudRepository_thenSuccess() {
 
  // given
  BookDocument bookDocument = 
    new BookDocument("lorem", "Foundation", "Isaac Asimov", "Once upon a time ...");
 
  // when
  bookDocumentCrudRepository.save(bookDocument);
  
  // then
  Iterable resultIterable = bookDocumentCrudRepository.findAll();
  List result = StreamSupport.stream(resultIterable.spliterator(), false)
                                           .collect(Collectors.toList());
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookDocument), is(true));
}

4.3. Использование области видимости на основе Пакетов

Наконец, мы можем указать базовые пакеты , в которых определены наши репозитории , используя @EnableCassandraRepositories и @EnableMongoRepositories аннотации:

@EnableCassandraRepositories(basePackages="com.baeldung.multipledatamodules.cassandra")
@EnableMongoRepositories(basePackages="com.baeldung.multipledatamodules.mongo")
public class SpringDataMultipleModules {

  public static void main(String[] args) {
    SpringApplication.run(SpringDataMultipleModules.class, args);
  }
}

Как мы видим в строках 1 и 2, этот режим конфигурации предполагает, что мы используем разные пакеты для репозиториев Cassandra и MongoDB .

5. Заключение

В этом руководстве мы настроили простое приложение Spring Boot для использования двух различных модулей данных Spring тремя способами.

В качестве первого примера мы расширили репозиторий Cassandra и MongoRepository и использовали простые классы для объектов домена.

В нашем втором подходе мы расширили общий интерфейс CrudRepository и полагались на аннотации для конкретных модулей, такие как @Table и @Document на наших управляемых объектах.

В конце концов, мы использовали обнаружение на основе пакетов при настройке приложения с помощью @EnableCassandraRepositories и @EnableMongoRepositories .

Как всегда, полный код доступен на GitHub .