Redis 存储库支持将对象持久化为哈希。 这需要 Object-to-Hash 转换,该转换由 . 默认实现用于将属性值映射到 Redis native 和从 Redis 本机映射。RedisConverterConverterbyte[]Spring中文文档

给定前面部分中的类型,默认映射如下所示:PersonSpring中文文档

_class = org.example.Person                 (1)
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand                            (2)
lastname = al’thor
address.city = emond's field                (3)
address.country = andor
1 该属性包含在根级别以及任何嵌套接口或抽象类型中。_class
2 简单属性值按路径映射。
3 复杂类型的属性由其点路径映射。
1 该属性包含在根级别以及任何嵌套接口或抽象类型中。_class
2 简单属性值按路径映射。
3 复杂类型的属性由其点路径映射。

数据映射和类型转换

本节介绍如何将类型映射到 Hash 表示形式以及从 Hash 表示形式映射到哈希表示形式:Spring中文文档

表 1.默认映射规则
类型 样本 映射值

简单类型
(例如,String)Spring中文文档

字符串 firstname = “rand”;Spring中文文档

firstname = “兰德”Spring中文文档

字节数组 (byte[])Spring中文文档

byte[] 图像 = “rand”.getBytes();Spring中文文档

image = “兰德”Spring中文文档

复杂类型
(例如,地址)Spring中文文档

地址地址 = new Address(“emond's field”);Spring中文文档

address.city = “伊蒙德的田野”Spring中文文档

简单类型列表
Spring中文文档

List<String> 昵称 = asList(“dragon reborn”, “lews therin”);Spring中文文档

昵称。[0] = “龙重生”,
昵称。[1] = “卢斯·瑟林”Spring中文文档

简单类型地图
Spring中文文档

Map<String, String> atts = asMap({“eye-color”, “grey”}, {“...Spring中文文档

atts.[eye-color] = “灰色”,
atts.[头发颜色] = “...Spring中文文档

复杂类型列表
Spring中文文档

List<Address> addresses = asList(new Address(“em...Spring中文文档

地址。[0].city = “Emond's Field”,
地址.[1].city = “...Spring中文文档

复杂类型地图
Spring中文文档

Map<String, Address> addresses = asMap({“home”, new Address(“em...Spring中文文档

地址。[home].city = “Emond's Field”,
地址.[work].city = “...Spring中文文档

由于平面表示结构,Map 键需要是简单类型,例如 或 。StringNumber

可以通过在 中注册相应的 来自定义映射行为。 这些转换器可以负责从单个和到单个以及 . 第一个适用于(例如)将复杂类型转换为(例如)仍然使用默认映射哈希结构的二进制 JSON 表示形式。 第二个选项提供对生成的哈希的完全控制。ConverterRedisCustomConversionsbyte[]Map<String, byte[]>Spring中文文档

将对象写入 Redis 哈希会从哈希中删除内容并重新创建整个哈希,因此未映射的数据将丢失。

以下示例显示了两个示例字节数组转换器:Spring中文文档

例 1.示例字节[]转换器
@WritingConverter
public class AddressToBytesConverter implements Converter<Address, byte[]> {

  private final Jackson2JsonRedisSerializer<Address> serializer;

  public AddressToBytesConverter() {

    serializer = new Jackson2JsonRedisSerializer<Address>(Address.class);
    serializer.setObjectMapper(new ObjectMapper());
  }

  @Override
  public byte[] convert(Address value) {
    return serializer.serialize(value);
  }
}

@ReadingConverter
public class BytesToAddressConverter implements Converter<byte[], Address> {

  private final Jackson2JsonRedisSerializer<Address> serializer;

  public BytesToAddressConverter() {

    serializer = new Jackson2JsonRedisSerializer<Address>(Address.class);
    serializer.setObjectMapper(new ObjectMapper());
  }

  @Override
  public Address convert(byte[] value) {
    return serializer.deserialize(value);
  }
}

使用前面的字节数组会生成类似于以下内容的输出:ConverterSpring中文文档

_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
address = { city : "emond's field", country : "andor" }

以下示例显示了转换器的两个示例:MapSpring中文文档

例 2.示例映射<字符串、字节[]>转换器
@WritingConverter
public class AddressToMapConverter implements Converter<Address, Map<String, byte[]>> {

  @Override
  public Map<String, byte[]> convert(Address source) {
    return singletonMap("ciudad", source.getCity().getBytes());
  }
}

@ReadingConverter
public class MapToAddressConverter implements Converter<Map<String, byte[]>, Address> {

  @Override
  public Address convert(Map<String, byte[]> source) {
    return new Address(new String(source.get("ciudad")));
  }
}

使用前面的 Map 会生成类似于以下内容的输出:ConverterSpring中文文档

_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
ciudad = "emond's field"
自定义转换对索引解析没有影响。二级索引仍会创建,即使对于自定义转换类型也是如此。
表 1.默认映射规则
类型 样本 映射值

简单类型
(例如,String)Spring中文文档

字符串 firstname = “rand”;Spring中文文档

firstname = “兰德”Spring中文文档

字节数组 (byte[])Spring中文文档

byte[] 图像 = “rand”.getBytes();Spring中文文档

image = “兰德”Spring中文文档

复杂类型
(例如,地址)Spring中文文档

地址地址 = new Address(“emond's field”);Spring中文文档

address.city = “伊蒙德的田野”Spring中文文档

简单类型列表
Spring中文文档

List<String> 昵称 = asList(“dragon reborn”, “lews therin”);Spring中文文档

昵称。[0] = “龙重生”,
昵称。[1] = “卢斯·瑟林”Spring中文文档

简单类型地图
Spring中文文档

Map<String, String> atts = asMap({“eye-color”, “grey”}, {“...Spring中文文档

atts.[eye-color] = “灰色”,
atts.[头发颜色] = “...Spring中文文档

复杂类型列表
Spring中文文档

List<Address> addresses = asList(new Address(“em...Spring中文文档

地址。[0].city = “Emond's Field”,
地址.[1].city = “...Spring中文文档

复杂类型地图
Spring中文文档

Map<String, Address> addresses = asMap({“home”, new Address(“em...Spring中文文档

地址。[home].city = “Emond's Field”,
地址.[work].city = “...Spring中文文档

由于平面表示结构,Map 键需要是简单类型,例如 或 。StringNumber
将对象写入 Redis 哈希会从哈希中删除内容并重新创建整个哈希,因此未映射的数据将丢失。
自定义转换对索引解析没有影响。二级索引仍会创建,即使对于自定义转换类型也是如此。

自定义类型映射

如果要避免将整个 Java 类名写入类型信息,并且希望使用键,则可以在要保留的实体类上使用注释。 如果需要进一步自定义映射,请查看 TypeInformationMapper 接口。 该接口的实例可以在 上配置,该接口可以在 上配置。@TypeAliasDefaultRedisTypeMapperMappingRedisConverterSpring中文文档

下面的示例演示如何为实体定义类型别名:Spring中文文档

例 3.为实体定义@TypeAlias
@TypeAlias("pers")
class Person {

}

生成的文档包含字段中的值。pers_classSpring中文文档

配置自定义类型映射

以下示例演示了如何在 :RedisTypeMapperMappingRedisConverterSpring中文文档

例 4.通过 Spring Java Config 配置自定义RedisTypeMapper
class CustomRedisTypeMapper extends DefaultRedisTypeMapper {
  //implement custom type mapping here
}
@Configuration
class SampleRedisConfiguration {

  @Bean
  public MappingRedisConverter redisConverter(RedisMappingContext mappingContext,
        RedisCustomConversions customConversions, ReferenceResolver referenceResolver) {

    MappingRedisConverter mappingRedisConverter = new MappingRedisConverter(mappingContext, null, referenceResolver,
            customTypeMapper());

    mappingRedisConverter.setCustomConversions(customConversions);

    return mappingRedisConverter;
  }

  @Bean
  public RedisTypeMapper customTypeMapper() {
    return new CustomRedisTypeMapper();
  }
}