天天看點

Spring中國教育管理中心-Apache Cassandra 的 Spring 資料教程十三

14.5.使用自定義轉換器覆寫預設映射

要對映射過程進行更細粒度的控制,您可以Converters使用 CassandraConverter實作注冊 Spring ,例如

MappingCassandraConverter.

MappingCassandraConverterConverters在嘗試映射對象本身之前,首先檢查是否有任何 Spring可以處理特定的類。要“劫持” MappingCassandraConverter(可能是為了提高性能或其他自定義映射需求)的正常映射政策,您需要建立 SpringConverter接口的實作并将其注冊到MappingCassandraConverter.

14.5.1.使用注冊的 Spring 轉換器進行儲存

您可以在一個過程中将轉換和儲存結合起來,基本上是使用轉換器來進行儲存。

以下示例使用 aConverter将Person對象轉換為java.lang.String 帶有 Jackson 2 的 a:

class PersonWriteConverter implements Converter<Person, String> {

public String convert(Person source) {

try {
  return new ObjectMapper().writeValueAsString(source);
} catch (IOException e) {
  throw new IllegalStateException(e);
}           

}

14.5.2.使用 Spring 轉換器讀取

與結合儲存和轉換的方式類似,您也可以結合閱讀和轉換。

以下示例使用 aConverter将 ajava.lang.String轉換為PersonJackson 2的對象:

class PersonReadConverter implements Converter<String, Person> {

public Person convert(String source) {

if (StringUtils.hasText(source)) {
  try {
    return new ObjectMapper().readValue(source, Person.class);
  } catch (IOException e) {
    throw new IllegalStateException(e);
  }
}

return null;           

14.5.3.注冊 Spring 轉換器CassandraConverter

Spring Data for Apache Cassandra Java 配置提供了一種注冊 SpringConverter執行個體的便捷方法:

MappingCassandraConverter. 以下配置片段顯示了如何手動注冊轉換器以及配置CustomConversions:

@Configuration

public class ConverterConfiguration extends AbstractCassandraConfiguration {

@Override

public CassandraCustomConversions customConversions() {

List<Converter<?, ?>> converters = new ArrayList<>();

converters.add(new PersonReadConverter());
converters.add(new PersonWriteConverter());

return new CassandraCustomConversions(converters);           

// other methods omitted...

以下 SpringConverter實作示例從 aString轉換為自定義Email值對象:

@ReadingConverter

public class EmailReadConverter implements Converter<String, Email> {

public Email convert(String source) {

return Email.valueOf(source);           

Spring中國教育管理中心-Apache Cassandra 的 Spring 資料教程十三

如果您編寫Converter的源類型和目标類型均為本機類型,我們無法确定是否應将其視為讀取轉換器或寫入轉換器。将轉換器執行個體注冊為兩者可能會導緻不需要的結果。例如, aConverter<String, Long>是不明确的,盡管在編寫時嘗試将所有String執行個體轉換為Long執行個體可能沒有意義。為了讓你強制基礎設施注冊一個轉換器,隻有一個辦法,我們提供@ReadingConverter并@WritingConverter在轉換器實作使用注解。

轉換器需要進行顯式注冊,因為不會從類路徑或容器掃描中提取執行個體,以避免不必要的轉換服務注冊以及此類注冊産生的副作用。轉換器注冊CustomConversions為中央工具,允許根據源和目标類型注冊和查詢已注冊的轉換器。

CustomConversions 附帶一組預定義的轉換器注冊:

JSR-310 轉換器,用于在java.time,java.util.Date和String類型之間進行轉換。

不推薦使用:Joda 時間轉換器,用于在org.joda.time、JSR-310 和java.util.Date.

已棄用:ThreeTenBackport 轉換器,用于在org.joda.time、JSR-310 和java.util.Date.

本地時間類型(例如LocalDateTimeto java.util.Date)的預設轉換器依賴于系統預設時區設定在這些類型之間進行轉換。您可以通過注冊您自己的轉換器來覆寫預設轉換器。

轉換器消歧

通常,我們會檢查Converter它們互相轉換的源和目标類型的實作。根據其中一個是否是底層資料通路 API 可以本地處理的類型,我們将轉換器執行個體注冊為讀取或寫入轉換器。以下示例顯示了一個寫入和讀取轉換器(注意差別在于 上的限定符的順序Converter):

// Write converter as only the target type is one that can be handled natively

class MyConverter implements Converter<Person, String> { … }

// Read converter as only the source type is one that can be handled natively

class MyConverter implements Converter<String, Person> { … }

14.6.實體狀态檢測政策

下表描述了 Spring Data 提供的用于檢測實體是否為新實體的政策:

14.7.生命周期事件

Cassandra 映射架構有幾個内置

org.springframework.context.ApplicationEvent事件,您的應用程式可以通過在ApplicationContext. 由于基于 Spring 的應用程式上下文事件基礎結構,其他産品(例如 Spring Integration)可以輕松接收這些事件,因為它們是基于 Spring 的應用程式中衆所周知的事件機制。

要在對象進入資料庫之前對其進行攔截,您可以注冊一個

org.springframework.data.cassandra.core.mapping.event.AbstractCassandraEventListener覆寫該onBeforeSave(…)方法的子類。當事件被排程時,你的監聽器被調用并傳遞域對象(它是一個 Java 實體)。以下示例使用該onBeforeSave方法:

class BeforeSaveListener extends AbstractCassandraEventListener {

@Override

public void onBeforeSave(BeforeSaveEvent event) {

// … change values, delete them, whatever …           

在 Spring 中聲明這些 beanApplicationContext将導緻在排程事件時調用它們。

AbstractCassandraEventListener具有以下回調方法:

onBeforeSave:在插入或更新資料庫中的行之前調用CassandraTemplate.insert(…)和.update(…)操作。

onAfterSave: 在資料庫中插入或更新行後調用CassandraTemplate…insert(…)和.update(…)操作。

onBeforeDelete: 在CassandraTemplate.delete(…)從資料庫中删除行之前的操作中調用。

onAfterDelete:CassandraTemplate.delete(…)從資料庫中删除行後在操作中調用。

onAfterLoad:從資料庫中檢索每一行後CassandraTemplate.select(…),在.slice(…)、 和.stream(…)方法中調用。

onAfterConvert:将從資料庫中檢索到的行轉換為 POJO 後CassandraTemplate.select(…),在.slice(…)、 和.stream(…)方法中調用。

僅針對根級别類型發出生命周期事件。在聚合根中用作屬性的複雜類型不受事件釋出的影響。

14.8.實體回調

Spring Data 基礎設施提供了在調用某些方法之前和之後修改實體的鈎子。那些所謂的EntityCallback執行個體提供了一種友善的方法來檢查和潛在地以回調風格修改實體。

AnEntityCallback看起來很像一個專門的ApplicationListener. 一些 Spring Data 子產品釋出BeforeSaveEvent允許修改給定實體的存儲特定事件(例如)。在某些情況下,例如使用不可變類型時,這些事件可能會導緻麻煩。此外,事件釋出依賴于

ApplicationEventMulticaster. 如果使用異步配置TaskExecutor它可能會導緻不可預測的結果,因為事件處理可以分叉到線程上。

實體回調為同步 API 和反應式 API 提供內建點,以保證在處理鍊中定義明确的檢查點按順序執行,傳回潛在修改的實體或反應式包裝器類型。

實體回調通常按 API 類型分隔。這種分離意味着同步 API 僅考慮同步實體回調,而反應式實作僅考慮反應式實體回調。

Spring Data Commons 2.2 引入了實體回調 API。這是應用實體修改的推薦方式。在調用可能已注冊的執行個體之前,ApplicationEvents仍會釋出特定于現有商店的資訊。EntityCallback