Spring Data Cassandra簡介
我們將從基礎開始,完成配置和編碼,最後構建一個完整的Spring Data Cassandra模組。
1.概述
本文使用Spring Data訪問與Cassandra的實用介紹。Cassandra是一個支援快速寫入的NoSQL資料庫,可以用作事件溯源的事件儲存等。
2. Maven依賴
讓我們首先使用Maven 定義pom.xml中的依賴項:
<dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>2.1.9</version> </dependency>
3. Cassandra的配置
我們將在整個過程中使用Java風格的配置來配置Cassandra整合。
3.1。主配置
讓我們從主配置類開始 - 當然是通過類級別@Configuration註釋驅動的:
@Configuration <b>public</b> <b>class</b> CassandraConfig <b>extends</b> AbstractCassandraConfiguration { @Override <b>protected</b> String getKeyspaceName() { <b>return</b> <font>"testKeySpace"</font><font>; } @Bean <b>public</b> CassandraClusterFactoryBean cluster() { CassandraClusterFactoryBean cluster = <b>new</b> CassandraClusterFactoryBean(); cluster.setContactPoints(</font><font>"127.0.0.1"</font><font>); cluster.setPort(9142); <b>return</b> cluster; } @Bean <b>public</b> CassandraMappingContext cassandraMapping() throws ClassNotFoundException { <b>return</b> <b>new</b> BasicCassandraMappingContext(); } } </font>
注意新的bean - BasicCassandraMappingContext - 帶有預設實現。這是在物件和持久格式之間對映永續性實體所必需的。
由於預設實現足夠,我們可以直接使用它。
3.2。Cassandra連線屬性
我們必須配置三個必需的設定來設定Cassandra客戶端的連線。
我們必須設定Cassandra伺服器作為contactPoints執行的主機名。埠只是伺服器中請求的偵聽埠。KeyspaceName是定義節點上資料複製的名稱空間,它基於Cassandra相關概念。
4. Cassandra儲存庫
我們將使用CassandraRepository作為資料訪問層。這遵循Spring Data儲存庫抽象,該抽象集中於抽象出跨不同永續性機制實現資料訪問層所需的程式碼。
4.1。建立CassandraRepository
讓我們建立要在配置中使用的CassandraRepository:
@Repository <b>public</b> <b>interface</b> BookRepository <b>extends</b> CassandraRepository<Book> { <font><i>//</i></font><font> } </font>
4.2。CassandraRepository的配置
現在,我們可以擴充套件第3.1節中的配置,新增@EnableCassandraRepositories類級別註釋來標記我們在CassandraConfig的 4.1節中建立的Cassandra儲存庫:
@Configuration @EnableCassandraRepositories( basePackages = <font>"org.baeldung.spring.data.cassandra.repository"</font><font>) <b>public</b> <b>class</b> CassandraConfig <b>extends</b> AbstractCassandraConfiguration { </font><font><i>//</i></font><font> } </font>
5.實體
讓我們快速瀏覽一下實體 - 我們將要使用的模型類。該類已註釋,併為嵌入模式下的元資料Cassandra資料表建立定義了其他引數。
使用@Table註釋,bean直接對映到Cassandra資料表。此外,每個屬性都定義為一種主鍵或一個簡單列:
@Table <b>public</b> <b>class</b> Book { @PrimaryKeyColumn( name = <font>"isbn"</font><font>, ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) <b>private</b> UUID id; @PrimaryKeyColumn( name = </font><font>"title"</font><font>, ordinal = 0, type = PrimaryKeyType.PARTITIONED) <b>private</b> String title; @PrimaryKeyColumn( name = </font><font>"publisher"</font><font>, ordinal = 1, type = PrimaryKeyType.PARTITIONED) <b>private</b> String publisher; @Column <b>private</b> Set<String> tags = <b>new</b> HashSet<>(); </font><font><i>// standard getters and setters</i></font><font> } </font>
6.使用嵌入式伺服器進行測試
6.1。Maven依賴
如果要在嵌入模式下執行Cassandra(無需手動安裝單獨的Cassandra伺服器),則需要將與cassandra-unit相關的依賴項新增到pom.xml:
<dependency> <groupId>org.cassandraunit</groupId> <artifactId>cassandra-unit-spring</artifactId> <version>2.1.9.2</version> <scope>test</scope> <exclusions> <exclusion> <groupId>org.cassandraunit</groupId> <artifactId>cassandra-unit</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.cassandraunit</groupId> <artifactId>cassandra-unit-shaded</artifactId> <version>2.1.9.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hectorclient</groupId> <artifactId>hector-core</artifactId> <version>2.0-0</version> </dependency>
可以使用嵌入式Cassandra伺服器來測試此應用程式。主要優點是您不希望顯式安裝Cassandra。
此嵌入式伺服器也與Spring JUnit Tests相容。在這裡,我們可以使用@RunWith註釋和嵌入式伺服器設定SpringJUnit4ClassRunner。因此,可以在不執行外部Cassandra服務的情況下實現完整的測試套件。
@RunWith(SpringJUnit4ClassRunner.<b>class</b>) @ContextConfiguration(<b>class</b>es = CassandraConfig.<b>class</b>) <b>public</b> <b>class</b> BookRepositoryIntegrationTest { <font><i>//</i></font><font> } </font>
6.2。啟動和停止伺服器
如果您正在執行外部Cassandra伺服器,則可以忽略此部分。
我們必須為整個測試套件啟動伺服器一次,因此伺服器啟動方法標有@BeforeClass註釋:
@BeforeClass <b>public</b> <b>static</b> <b>void</b> startCassandraEmbedded() { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); Cluster cluster = Cluster.builder() .addContactPoints(<font>"127.0.0.1"</font><font>).withPort(9142).build(); Session session = cluster.connect(); } </font>
接下來,我們必須確保在完成測試套件執行後伺服器停止:
@AfterClass <b>public</b> <b>static</b> <b>void</b> stopCassandraEmbedded() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); }
6.3。清潔資料表
最好在每次測試執行之前刪除並建立資料表,以避免由於早期測試執行中的操作資料而導致的意外結果。
現在我們可以在伺服器啟動時建立資料表:
@Before <b>public</b> <b>void</b> createTable() { adminTemplate.createTable( <b>true</b>, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.<b>class</b>, <b>new</b> HashMap<String, Object>()); }
在每個測試用例執行後刪除:
@After <b>public</b> <b>void</b> dropTable() { adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME)); }
7.使用CassandraRepository進行資料訪問
我們可以直接使用上面建立的BookRepository來持久化,操作和獲取Cassandra資料庫中的資料。
7.1。儲存一本新書
我們可以將新書儲存到我們的書店:
Book javaBook = <b>new</b> Book( UUIDs.timeBased(), <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>, ImmutableSet.of(</font><font>"Computer"</font><font>, </font><font>"Software"</font><font>)); bookRepository.save(ImmutableSet.of(javaBook)); </font>
然後我們可以檢查資料庫中插入的書的可用性:
Iterable<Book> books = bookRepository.findByTitleAndPublisher( <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>); assertEquals(javaBook.getId(), books.iterator().next().getId()); </font>
7.2。更新現有圖書
Lat首先插入一本新書:
Book javaBook = <b>new</b> Book( UUIDs.timeBased(), <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>, ImmutableSet.of(</font><font>"Computer"</font><font>, </font><font>"Software"</font><font>)); bookRepository.save(ImmutableSet.of(javaBook)); </font>
讓我們按標題取書:
Iterable<Book> books = bookRepository.findByTitleAndPublisher( <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>); </font>
然後讓我們改變這本書的標題:
javaBook.setTitle(<font>"Head First Java Second Edition"</font><font>); bookRepository.save(ImmutableSet.of(javaBook)); </font>
最後讓我們檢查標題是否在資料庫中更新:
Iterable<Book> books = bookRepository.findByTitleAndPublisher( <font>"Head First Java Second Edition"</font><font>, </font><font>"O'Reilly Media"</font><font>); assertEquals( javaBook.getTitle(), updateBooks.iterator().next().getTitle()); </font>
7.3。刪除現有圖書
插入一本新書:
Book javaBook = <b>new</b> Book( UUIDs.timeBased(), <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>, ImmutableSet.of(</font><font>"Computer"</font><font>, </font><font>"Software"</font><font>)); bookRepository.save(ImmutableSet.of(javaBook)); </font>
然後刪除新輸入的書:
bookRepository.delete(javaBook);
現在我們可以檢查刪除:
Iterable<Book> books = bookRepository.findByTitleAndPublisher( <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>); assertNotEquals(javaBook.getId(), books.iterator().next().getId()); </font>
這將導致從程式碼中丟擲NoSuchElementException,確保刪除該書。
7.4。查詢所有書籍
首先插入新書:
Book javaBook = <b>new</b> Book( UUIDs.timeBased(), <font>"Head First Java"</font><font>, </font><font>"O'Reilly Media"</font><font>, ImmutableSet.of(</font><font>"Computer"</font><font>, </font><font>"Software"</font><font>)); Book dPatternBook = <b>new</b> Book( UUIDs.timeBased(), </font><font>"Head Design Patterns"</font><font>,</font><font>"O'Reilly Media"</font><font>, ImmutableSet.of(</font><font>"Computer"</font><font>, </font><font>"Software"</font><font>)); bookRepository.save(ImmutableSet.of(javaBook)); bookRepository.save(ImmutableSet.of(dPatternBook)); </font>
查詢所有書籍:
Iterable<Book> books = bookRepository.findAll();
然後我們可以檢視資料庫中可用書籍的數量:
<b>int</b> bookCount = 0; <b>for</b> (Book book : books) bookCount++; assertEquals(bookCount, 2);
8.結論
我們使用最常用的CassandraRepository資料訪問機制,使用Spring資料對Cassandra進行了基本的動手介紹。
上面的程式碼片段和示例的實現可以在ofollow,noindex" target="_blank">我的GitHub專案中 中找到- 這是一個基於Eclipse的專案,因此它應該很容易匯入和執行。