基于属性的转换器
在 基于类型的转换 已经提供了影响目标存储中特定类型的转换和表示的方法,但当仅考虑特定类型的某些值或属性进行转换时,它存在局限性。基于属性的转换器允许在每个属性的基础上配置转换规则,可以通过声明性方式(使用 @ValueConverter
)或通过编程方式(为特定属性注册 PropertyValueConverter
)来实现。
一个 PropertyValueConverter
可以将给定的值转换为其存储表示(写入)并反向转换(读取),如下所示。附加的 ValueConversionContext
提供了额外的信息,例如映射元数据和直接的 read
和 write
方法。
示例 1. 一个简单的 PropertyValueConverter
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);
}
}
您可以通过委托给 PropertyValueConversions
,通常使用 PropertyValueConverterFactory
来提供实际的转换器,从 CustomConversions#getPropertyValueConverter(…)
获取 PropertyValueConverter
实例。根据您的应用需求,您可以链式调用或装饰多个 PropertyValueConverterFactory
实例,例如,用于应用缓存。默认情况下,Spring Data Cassandra 使用一种缓存实现,可以处理具有默认构造函数或枚举值的类型。可以通过 PropertyValueConverterFactory
中的工厂方法访问一组预定义的工厂。您可以使用 PropertyValueConverterFactory.beanFactoryAware(…)
从 ApplicationContext
获取 PropertyValueConverter
实例。
您可以通过 ConverterConfiguration
更改默认行为。
声明式值转换器
最直接使用 PropertyValueConverter
的方法是通过使用 @ValueConverter
注解来标注属性,该注解定义了转换器类型:
示例 2. 声明式 PropertyValueConverter
class Person {
@ValueConverter(ReversingValueConverter.class)
String ssn;
}
程序化值转换器注册
程序化注册通过使用 PropertyValueConverterRegistrar
为实体模型中的属性注册 PropertyValueConverter
实例,以下示例展示了这一点。声明式注册与程序化注册的区别在于,程序化注册完全发生在实体模型之外。这种方法在无法或不希望注解实体模型时非常有用。
示例 3. 编程方式注册 PropertyValueConverter
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));
为通过名称标识的字段注册一个转换器。
类型安全的变体,允许注册一个转换器及其转换函数。此方法使用类代理来确定属性。确保类和访问器都不是
final
,否则此方法将无法工作。
点表示法(例如 registerConverter(Person.class, "address.street", …)
)用于在注册转换器时跨属性导航到嵌套对象是 不 支持的。
模式推导只能从注册的转换器中推导列类型,如果转换器是一个 PropertyValueConverter
类。无法从 lambda 表达式中确定泛型,使用 lambda 表达式将回退到属性类型。
CassandraValueConverter
提供了一个预定义的 PropertyValueConverter
接口,使用 CassandraConversionContext
。
CassandraCustomConversions 配置
默认情况下,CassandraCustomConversions
可以处理声明式的值转换器,具体取决于配置的 PropertyValueConverterFactory
。CassandraConverterConfigurationAdapter
帮助你设置编程式的值转换,或定义要使用的 PropertyValueConverterFactory
,或者注册转换器。
示例 4. 配置示例
CassandraCustomConversions conversions = CassandraCustomConversions.create(adapter -> {
adapter.registerConverter(…);
adapter.configurePropertyConversions(registrar -> {
registrar.registerConverter(Person.class, "name", String.class)
.writing((from, ctx) -> …)
.reading((from, ctx) -> …);
});
});