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