オブジェクトからハッシュへのマッピング

Redis リポジトリのサポートは、オブジェクトをハッシュに永続化します。これには、RedisConverter によって実行されるオブジェクトからハッシュへの変換が必要です。デフォルトの実装では、Redis ネイティブ byte[] との間でプロパティ値をマッピングするために Converter を使用します。

前のセクションの Person 型を考えると、デフォルトのマッピングは次のようになります。

_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: デフォルトのマッピングルール
タイプ サンプル マップされた値

シンプル型
(たとえば、文字列)

String firstname="rand" ;

名 = " ランド "

Byte 配列 (byte[])

byte[] image="rand" .getBytes();

image="rand"

複合型
(たとえば、住所)

住所 address = new Address("emond ’ s field");

address.city=" モンドのフィールド "

リスト
シンプル型

List<String> nicknames = asList("dragon reborn", "lews therin");

ニックネーム。[0] =「生まれ変わったドラゴン」、
ニックネーム。[1] = "lews therin"

地図
シンプル型

Map<String, String> atts = asMap({" 目の色 ", " 灰色 "}, {" …

atts。[eye-color] = "grey"、
atts。[hair-color] = " …

リスト
複合型

リスト <Address> アドレス = asList(新しいアドレス ("em …

addresss。[0] .city = "emond's field"、
アドレス。[1] .city = " …

地図
複合型

Map<String, Address> アドレス = asMap({"home" , new Address("em …

addresss。[home] .city = "emond's field"、
addresss。[work] .city = " …

フラットな表現構造のため、マップキーは String や Number などの単純な型である必要があります。

対応する Converter を RedisCustomConversions に登録することにより、マッピング動作をカスタマイズできます。これらのコンバーターは、Map<String, byte[]> だけでなく、単一の byte[] との間の変換も処理できます。1 つ目は、(たとえば)複合型を(たとえば)デフォルトのマッピングハッシュ構造を使用するバイナリ JSON 表現に変換するのに適しています。2 番目のオプションは、結果のハッシュを完全に制御します。

Redis ハッシュにオブジェクトを書き込むと、ハッシュからコンテンツが削除され、ハッシュ全体が再作成されるため、マップされていないデータは失われます。

次の例は、2 つのサンプルバイト配列コンバーターを示しています。

例 1: サンプル byte[] コンバーター
@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);
  }
}

上記のバイト配列 Converter を使用すると、次のような出力が生成されます。

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

次の例は、Map コンバーターの 2 つの例を示しています。

例 2: サンプルマップ <String, byte[]> コンバーター
@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")));
  }
}

上記のマップ Converter を使用すると、次のような出力が生成されます。

_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
ciudad = "emond's field"
カスタム変換は、インデックスの解決には影響しません。カスタム変換された型の場合でも、二次インデックスは引き続き作成されます。

型マッピングのカスタマイズ

Java クラス名全体を型情報として記述したくない場合で、キーを使用したい場合は、永続化されるエンティティクラスで @TypeAlias アノテーションを使用できます。マッピングをさらにカスタマイズする必要がある場合は、TypeInformationMapper (Javadoc) インターフェースを確認してください。そのインターフェースのインスタンスは、MappingRedisConverter で構成できる DefaultRedisTypeMapper で構成できます。

次の例は、エンティティの型エイリアスを定義する方法を示しています。

例 3: エンティティの @TypeAlias の定義
@TypeAlias("pers")
class Person {

}

結果のドキュメントには、_class フィールドの値として pers が含まれています。

カスタム型マッピングの構成

次の例は、MappingRedisConverter でカスタム RedisTypeMapper を構成する方法を示しています。

例 4: Spring JavaConfig を介したカスタム 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();
  }
}