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 Listresult = 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 IterableresultIterable = 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 .