Property-based Converters

虽然 type-based conversion 已提供影响目标商店中某些类型的转换和表示的方法,但仅考虑特定类型的某些值或属性进行转换时,它存在局限性。基于属性的转换器允许基于每个属性配置转换规则,既可声明式(通过 @ValueConverter)也可编程方式(为特定属性注册 PropertyValueConverter)。 PropertyValueConverter 可将给定值转换为其存储表示(写)并转换回来(读),如下列表所示。附加的 ValueConversionContext 提供附加信息,如映射元数据以及直接的 readwrite 方法。 .A simple PropertyValueConverter

/*
 * Copyright 2020-2024 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.data.cassandra.example;

// tag::class[]
class ReversingValueConverter implements PropertyValueConverter<String, String, ValueConversionContext> {

	@Override
	public String read(String value, ValueConversionContext context) {
		return reverse(value);
	}

	@Override
	public String write(String value, ValueConversionContext context) {
		return reverse(value);
	}

	// end::class[]
	private String reverse(String source) {

		if (source == null) {
			return null;
		}

		return new StringBuilder(source).reverse().toString();
	}
	// tag::class[]
}
// end::class[]

您可以通过委托到 PropertyValueConversionsCustomConversions#getPropertyValueConverter(…) 获取 PropertyValueConverter 实例,通常情况下,通过使用 PropertyValueConverterFactory 提供实际的转换器。根据您的应用程序的需求,您可以链接或装饰 PropertyValueConverterFactory 的多个实例——例如,应用缓存。默认情况下,Spring Data Cassandra 使用一种可以处理具有默认构造函数或枚举值的类型的缓存实现。您可以通过 PropertyValueConverterFactory 中的工厂方法获得一组预定义的工厂。您可以使用 PropertyValueConverterFactory.beanFactoryAware(…)ApplicationContext 中获得 PropertyValueConverter 实例。 可以通过 ConverterConfiguration 更改默认行为。

Declarative Value Converter

PropertyValueConverter 最直接的用法是使用 @ValueConverter 注释注释属性,该注释定义转换器类型:

Example 1. Declarative PropertyValueConverter
class Person {

  @ValueConverter(ReversingValueConverter.class)
  String ssn;
}

Programmatic Value Converter Registration

编程注册使用 PropertyValueConverterRegistrar 为实体模型中的属性注册 PropertyValueConverter 实例,如下例所示。声明注册和编程注册之间的区别在于编程注册完全在实体模型外部发生。如果您不能或不想对实体模型进行注释,这种方法很有用。

Example 2. Programmatic PropertyValueConverter registration
PropertyValueConverterRegistrar registrar = new PropertyValueConverterRegistrar();

registrar.registerConverter(Address.class, "street", new PropertyValueConverter() { … }); 1

// type safe registration
registrar.registerConverter(Person.class, Person::getSsn())                               2
  .writing(value -> encrypt(value))
  .reading(value -> decrypt(value));
1 11. 为通过其名称标识的字段注册一个转换器。
2 12. 允许注册转换器及其转换函数的类型安全变体。此方法使用类代理来确定属性。确保类和访问器都不是`final`,否则此方法将不起作用。

当注册转换器时,点表示法(如 registerConverter(Person.class, "address.street", …))用于在属性之间导航到嵌套对象时,将 not 受支持。

仅当转换器是 PropertyValueConverter 类时,模式导出才能从注册转换器导出列类型。Lambda 无法确定泛型,使用 Lambda 将回退为属性类型。

CassandraValueConverter 提供了一个预类型 PropertyValueConverter 接口,它使用 CassandraConversionContext

CassandraCustomConversions configuration

默认情况下,CassandraCustomConversions 可以处理声明的值转换器,具体取决于配置的 PropertyValueConverterFactoryCassandraConverterConfigurationAdapter 帮助您设置编程值转换或定义要使用的 PropertyValueConverterFactory 或注册转换器。

Example 3. Configuration Sample
CassandraCustomConversions conversions = CassandraCustomConversions.create(adapter -> {
  adapter.registerConverter(…);
  adapter.configurePropertyConversions(registrar -> {
    registrar.registerConverter(Person.class, "name", String.class)
        .writing((from, ctx) -> …)
        .reading((from, ctx) -> …);
  });
});