ReactiveCassandraTemplate 為您提供了一種簡(jiǎn)單的方法來(lái)保存、更新和刪除域?qū)ο蟛⑦@些對(duì)象映射到 Cassandra 中管理的表。
CassandraTemplate有幾種方便的方法來(lái)保存和插入您的對(duì)象。要對(duì)轉(zhuǎn)換過(guò)程進(jìn)行更細(xì)粒度的控制,您可以Converter使用MappingCassandraConverter (例如,Converter<Row, Person>)注冊(cè) Spring實(shí)例。
插入和更新操作的區(qū)別在于INSERT操作不插入null值。
使用該INSERT操作的簡(jiǎn)單案例是保存一個(gè) POJO。在這種情況下,表名由簡(jiǎn)單的類(lèi)名(而不是完全限定的類(lèi)名)確定??梢允褂糜成湓獢?shù)據(jù)覆蓋存儲(chǔ)對(duì)象的表。
插入或更新時(shí),id必須設(shè)置該屬性。Apache Cassandra 無(wú)法生成 ID。
以下示例使用保存操作并檢索其內(nèi)容:
示例 67. 使用 CassandraTemplate
import static org.springframework.data.cassandra.core.query.Criteria.where;import static org.springframework.data.cassandra.core.query.Query.query; … Person bob = new Person("Bob", 33); cassandraTemplate.insert(bob); Mono<Person> queriedBob = reactiveCassandraTemplate.selectOneById(query(where("age").is(33)), Person.class);
您可以使用以下操作進(jìn)行插入和保存:
void insert (Object objectToSave):在 Apache Cassandra 表中插入對(duì)象。
WriteResult 插入 (Object objectToSave, InsertOptions options):在 Apache Cassandra 表中插入對(duì)象并應(yīng)用InsertOptions。
您可以使用以下更新操作:
void update (Object objectToSave):更新 Apache Cassandra 表中的對(duì)象。
WriteResult 更新 (Object objectToSave, UpdateOptions options):更新 Apache Cassandra 表中的對(duì)象并應(yīng)用UpdateOptions。
您還可以使用老式的方式編寫(xiě)自己的 CQL 語(yǔ)句,如下例所示:
String cql = "INSERT INTO person (age, name) VALUES (39, 'Bob')"; Mono<Boolean> applied = reactiveCassandraTemplate.getReactiveCqlOperations().execute(cql);
您還可以在使用InsertOptions和時(shí)配置其他選項(xiàng),例如 TTL、一致性級(jí)別和輕量級(jí)事務(wù)UpdateOptions。
您可以通過(guò)兩種方式管理用于對(duì)表進(jìn)行操作的表名。默認(rèn)表名是更改為以小寫(xiě)字母開(kāi)頭的簡(jiǎn)單類(lèi)名。因此,com.example.Person類(lèi)的一個(gè)實(shí)例將存儲(chǔ)在person表中。第二種方式是在@Table注解中指定表名。
對(duì)于更新,您可以選擇更新多行。
以下示例顯示了通過(guò)向具有+分配的余額添加一次性 50.00 美元獎(jiǎng)金來(lái)更新單個(gè)帳戶對(duì)象:
示例 68. 使用更新行 ReactiveCasandraTemplate
import static org.springframework.data.cassandra.core.query.Criteria.where;import org.springframework.data.cassandra.core.query.Query;import org.springframework.data.cassandra.core.query.Update; … Mono<Boolean> wasApplied = reactiveCassandraTemplate.update(Query.query(where("id").is("foo")), Update.create().increment("balance", 50.00), Account.class);
除了Query前面討論的之外,我們還通過(guò)使用Update對(duì)象來(lái)提供更新定義。該Update班有匹配可用的Apache Cassandra的更新任務(wù),從而方法。
大多數(shù)方法返回Update對(duì)象以提供用于代碼樣式目的的流暢 API。
有關(guān)更多詳細(xì)信息,請(qǐng)參閱“為行執(zhí)行更新的方法”。
本章涵蓋了對(duì) Apache Cassandra 的 Spring Data Repository 支持的詳細(xì)信息。Cassandra 的存儲(chǔ)庫(kù)支持建立在“使用 Spring 數(shù)據(jù)存儲(chǔ)庫(kù)”中解釋的核心存儲(chǔ)庫(kù)支持之上。Cassandra 存儲(chǔ)庫(kù)將CassandraTemplate其CqlTemplate用作基礎(chǔ)設(shè)施 bean。在繼續(xù)之前,您應(yīng)該了解那里解釋的基本概念。
要訪問(wèn)存儲(chǔ)在 Apache Cassandra 中的域?qū)嶓w,您可以使用 Spring Data 復(fù)雜的存儲(chǔ)庫(kù)支持,這大大簡(jiǎn)化了 DAO 的實(shí)現(xiàn)。為此,請(qǐng)為您的存儲(chǔ)庫(kù)創(chuàng)建一個(gè)接口,如以下示例所示:
示例 69. 示例 Person 實(shí)體
@Tablepublic class Person { @Id private String id; private String firstname; private String lastname; // … getters and setters omitted}
請(qǐng)注意,該實(shí)體有一個(gè)名為idtype的屬性String。中使用的默認(rèn)序列化機(jī)制CassandraTemplate(支持存儲(chǔ)庫(kù)支持)將命名的屬性id視為行 ID。
以下示例顯示了用于持久化Person實(shí)體的存儲(chǔ)庫(kù)定義:
示例 70. 用于持久化Person實(shí)體的基本存儲(chǔ)庫(kù)接口
public interface PersonRepository extends CrudRepository<Person, String> { // additional custom finder methods go here}
目前,前面示例中的接口僅用于鍵入目的,但稍后我們會(huì)向其添加其他方法。
接下來(lái),在您的 Spring 配置中,添加以下內(nèi)容(如果您使用 Java 進(jìn)行配置):
如果要使用 Java 配置,請(qǐng)使用@
EnableCassandraRepositories注解。注釋帶有與命名空間元素相同的屬性。如果沒(méi)有配置基礎(chǔ)包,基礎(chǔ)設(shè)施會(huì)掃描帶注釋的配置類(lèi)的包。下面的例子展示了如何使用@EnableCassandraRepositories注解:
示例 71. 存儲(chǔ)庫(kù)的 Java 配置
@Configuration@EnableCassandraRepositoriesclass ApplicationConfig extends AbstractCassandraConfiguration { @Override protected String getKeyspaceName() { return "keyspace"; } public String[] getEntityBasePackages() { return new String[] { "com.oreilly.springdata.cassandra" }; } }
如果您想使用 XML 配置,那么以下示例顯示了一個(gè)最小的配置片段:
示例 72.Cassandra 存儲(chǔ)庫(kù) Spring XML 配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra" xsi:schemaLocation=" http://www.springframework.org/schema/data/cassandra https://www.springframework.org/schema/data/cassandra/spring-cassandra.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <cassandra:session port="9042" keyspace-name="keyspaceName"/> <cassandra:mapping entity-base-packages="com.acme.*.entities"> </cassandra:mapping> <cassandra:converter/> <cassandra:template/> <cassandra:repositories base-package="com.acme.*.entities"/></beans>
的cassandra:repositories命名空間元素使得用于擴(kuò)展接口將被掃描的基本包CrudRepository為每一個(gè)發(fā)現(xiàn),創(chuàng)建彈簧豆。默認(rèn)情況下,存儲(chǔ)庫(kù)與一個(gè)CassandraTemplate名為的Spring bean 連接cassandraTemplate,因此cassandra-template-ref如果您偏離此約定,您只需顯式配置 。
因?yàn)槲覀兊挠虼鎯?chǔ)庫(kù)擴(kuò)展了CrudRepository,它為您提供了基本的 CRUD 操作。使用存儲(chǔ)庫(kù)實(shí)例是將存儲(chǔ)庫(kù)作為依賴(lài)項(xiàng)注入客戶端的問(wèn)題,如以下示例通過(guò)自動(dòng)裝配所做的PersonRepository:
示例 73. 對(duì) Person 實(shí)體的基本訪問(wèn)
@RunWith(SpringRunner.class)@ContextConfigurationpublic class PersonRepositoryTests { @Autowired PersonRepository repository; @Test public void readsPersonTableCorrectly() { List<Person> persons = repository.findAll(); assertThat(persons.isEmpty()).isFalse(); } }
Cassandra 存儲(chǔ)庫(kù)支持對(duì)實(shí)體進(jìn)行分頁(yè)和排序訪問(wèn)的分頁(yè)和排序。Cassandra 分頁(yè)需要分頁(yè)狀態(tài)才能向前瀏覽頁(yè)面。ASlice跟蹤當(dāng)前的分頁(yè)狀態(tài)并允許創(chuàng)建一個(gè)Pageable請(qǐng)求下一頁(yè)。以下示例顯示如何設(shè)置對(duì)Person實(shí)體的分頁(yè)訪問(wèn):
示例 74. 對(duì)Person實(shí)體的分頁(yè)訪問(wèn)
@RunWith(SpringRunner.class)@ContextConfigurationpublic class PersonRepositoryTests { @Autowired PersonRepository repository; @Test public void readsPagesCorrectly() { Slice<Person> firstBatch = repository.findAll(CassandraPageRequest.first(10)); assertThat(firstBatch).hasSize(10); Page<Person> nextBatch = repository.findAll(firstBatch.nextPageable()); // … } }
Cassandra 存儲(chǔ)庫(kù)不擴(kuò)展
PagingAndSortingRepository,因?yàn)槭褂孟拗?偏移的經(jīng)典分頁(yè)模式不適用于 Cassandra。
前面的示例使用 Spring 的單元測(cè)試支持創(chuàng)建了一個(gè)應(yīng)用程序上下文,它執(zhí)行基于注解的依賴(lài)注入到測(cè)試類(lèi)中。在測(cè)試用例(測(cè)試方法)中,我們使用存儲(chǔ)庫(kù)來(lái)查詢數(shù)據(jù)存儲(chǔ)。我們調(diào)用請(qǐng)求所有Person實(shí)例的存儲(chǔ)庫(kù)查詢方法。
您通常在存儲(chǔ)庫(kù)上觸發(fā)的大多數(shù)數(shù)據(jù)訪問(wèn)操作都會(huì)導(dǎo)致對(duì) Apache Cassandra 數(shù)據(jù)庫(kù)執(zhí)行查詢。定義這樣的查詢就是在存儲(chǔ)庫(kù)接口上聲明一個(gè)方法。以下示例顯示了許多此類(lèi)方法聲明:
示例 75.帶有查詢方法的 PersonRepository
public interface PersonRepository extends CrudRepository<Person, String> { List<Person> findByLastname(String lastname); Slice<Person> findByFirstname(String firstname, Pageable pageRequest); List<Person> findByFirstname(String firstname, QueryOptions opts); List<Person> findByFirstname(String firstname, Sort sort); Person findByShippingAddress(Address address); Person findFirstByShippingAddress(Address address); Stream<Person> findAllBy(); @AllowFiltering List<Person> findAllByAge(int age); }
該方法顯示了對(duì)所有具有給定 的人的查詢lastname。查詢?cè)醋越馕黾s束的方法名稱(chēng),可以與And. 因此,方法名稱(chēng)導(dǎo)致查詢表達(dá)式為SELECT * FROM person WHERE lastname = 'lastname'。
將分頁(yè)應(yīng)用于查詢。您可以為您的方法簽名配備一個(gè)Pageable參數(shù),并讓該方法返回一個(gè)Slice實(shí)例,我們會(huì)相應(yīng)地自動(dòng)分頁(yè)查詢。
傳遞QueryOptions對(duì)象在執(zhí)行之前將查詢選項(xiàng)應(yīng)用于結(jié)果查詢。
對(duì)查詢應(yīng)用動(dòng)態(tài)排序。您可以Sort向方法簽名添加參數(shù),Spring Data 會(huì)自動(dòng)將排序應(yīng)用于查詢。
表明您可以使用 中Converter注冊(cè)的實(shí)例基于非原始類(lèi)型的屬性進(jìn)行查詢CustomConversions。
IncorrectResultSizeDataAccessException如果找到多個(gè)匹配項(xiàng),則拋出。
使用First關(guān)鍵字將查詢限制為僅第一個(gè)結(jié)果。與前面的方法不同,如果找到多個(gè)匹配項(xiàng),則此方法不會(huì)引發(fā)異常。
Stream在迭代流時(shí)使用 Java 8讀取和轉(zhuǎn)換單個(gè)元素。
顯示帶有@AllowFiltering,注釋的查詢方法,以允許服務(wù)器端過(guò)濾。
查詢非主鍵屬性需要二級(jí)索引。
下表顯示了可以在查詢方法中使用的關(guān)鍵字的簡(jiǎn)短示例:
聯(lián)系客服