知識庫 / Spring RSS 訂閱

多模塊 Spring Data 倉庫

Spring,Spring Data
HongKong
10
01:11 PM · Dec 06 ,2025

1. 引言

有時,我們需要在同一個應用程序中連接到多種數據庫技術。

在本教程中,我們將探討在同一應用程序中使用多個 Spring Data 模塊時的各種配置選項。

讓我們使用一個簡單的 Spring Boot 書店來探索這個主題。

2. 所需依賴

首先,我們需要在 pom.xml 文件中添加我們的依賴,以便我們可以使用 Spring Boot Data 的 spring-boot-starter-data-mongodbspring-boot-starter-data-cassandra 綁定。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-cassandra</artifactId>
  <version>3.1.5</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
  <version>3.1.5</version>
</dependency>

3. 數據庫設置

接下來,我們需要通過使用預構建的 Docker 鏡像,設置實際的數據庫。這些鏡像包含 CassandraMongo

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

這兩個命令將自動下載最新的 Cassandra 和 MongoDB Docker 鏡像並運行實際容器。

此外,還需要通過 -p 選項將端口轉發到實際操作系統環境中的容器內部,以便我們的應用程序可以訪問數據庫。

必須使用 cqlsh 工具創建 Cassandra 的數據庫結構。CassandraDataAutoConfiguration 不能自動創建 Keyspace,因此我們需要使用 CQL 語法進行聲明。

首先,我們需要連接到 Cassandra 容器的 bash shell:

$ docker exec -it cassandra-db /bin/bash
root@419acd18891e:/# 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行,我們創建了相關的 keyspace 和表。

我們可以跳過創建表的步驟,僅僅依賴 spring-boot-starter-data-cassandra 來為我們初始化模式,但由於我們希望分別探索框架配置,因此這是一個必要的步驟。

默認情況下,MongoDB 不會對模式進行任何驗證因此不需要進行任何其他配置

最後,我們在 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. 數據存儲檢測機制

當 classpath 上檢測到多個 Spring Data 模塊時,Spring 框架將進入嚴格的倉庫配置模式。這意味着它會使用不同的檢測機制,以確定哪個倉庫屬於哪種持久化技術。

4.1. 擴展模塊特定倉庫接口

以下機制嘗試確定一個倉庫是否擴展了 Spring Data 模塊特定倉庫類型:

public interface BookAuditRepository extends CassandraRepository<BookAudit, String> {

}

為了説明目的,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<BookDocument, String> {

}

此項存儲書籍的內容以及與其相關的元數據。

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

當應用程序上下文加載時,框架將使用其派生出的基本類來匹配每個存儲庫類型

@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<BookAudit> result = bookAuditRepository.findAll();
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookAudit), is(true));
}

你可以注意到我們的領域類是簡單的Java對象。在這種特定情況下,Cassandra數據庫模式必須由外部創建,使用CQL,正如我們在第3節中所做的那樣。

4.2. 使用領域對象模塊特定註解

第二種策略通過對領域對象上的模塊特定註解來確定持久化技術。

讓我們擴展一個通用的CrudRepostitory,並現在依賴於管理對象註解進行檢測:

public interface BookAuditCrudRepository extends CrudRepository<BookAudit, String> {

}
public interface BookDocumentCrudRepository extends CrudRepository<BookDocument, String> {

}

現在,BookAudit.java 已被標註為 Cassandra 相關的 @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
}

我們選擇 bookIdrentalRecNo 組合作為我們的唯一標識標準,因為我們的應用程序每次當有人借閲書籍時,都會簡單地記錄一條新的借閲記錄。

對於 BookDocument.java,我們使用 @Document 註解,該註解是 MongoDB 專用的:

@Document
public class BookDocument {

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

使用 <em>CrudRepository</em> 觸發 <em>BookDocument</em> 的保存仍然成功,但返回類型已從 <em>List</em> 變為 <em>Iterable</em>

@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<BookDocument> resultIterable = bookDocumentCrudRepository.findAll();
  List<BookDocument> result = StreamSupport.stream(resultIterable.spliterator(), false)
                                           .collect(Collectors.toList());
  assertThat(result.isEmpty(), is(false));
  assertThat(result.contains(bookDocument), is(true));
}

4.3. 使用基於包的命名空間

最後,我們可以指定我們的倉庫定義的基礎包,通過使用 <em @EnableCassandraRepositories</em><em @EnableMongoRepositories</em> 註解來實現:

@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 Data 模塊,並有三種方式實現。

首先,我們擴展了 <em >CassandraRepository</em><em >MongoRepository</em>,並使用簡單的類來定義領域對象。

其次,我們擴展了通用的 <em >CrudRepository</em> 接口,並依賴於模塊特定的註解,如 <em >@Table</em><em >@Document</em>,應用於我們的管理對象。

最後,我們使用基於包的檢測,通過 <em >@EnableCassandraRepositories</em><em >@EnableMongoRepositories</em> 配置應用程序。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.