1. 程式人生 > >Spring Redis(6)Redis持久化

Spring Redis(6)Redis持久化

Redis持久化

RedisRepositories能夠簡化將實體存入Hash的操作,並自動維護索引欄位。只需要象Hibernate那樣使用save、delete等簡單方法即可持久化資料到Redis。

Redis Repositories最低需要Redis 2.8.0.

簡單使用

定義實體


// 定義Redis實體的keyspace為persons
@RedisHash("persons")
public class Person {

  // 每個Redis實體必須有且只有一個@Id
  @Id 
  String id;
  String firstname;
  String lastname;
  Address address;
}

public
class Address { String city; String country; }

定義Repository 介面,CrudRepository 提供基本的CRUD和查詢方法,Spring將自動生成該介面的實現類



public interface PersonRepository extends CrudRepository<Person, String> {

}

定義配置類,預設掃描配置類所在包下的類,可以通過註解EnableRedisRepositories的引數來指定掃描的包,如@EnableRedisRepositories({“com.htfg.*”})

@Configuration
@EnableRedisRepositories
public class ApplicationConfig {

  @Bean
  public RedisConnectionFactory connectionFactory() {
    return new JedisConnectionFactory();
  }

  @Bean
  public RedisTemplate<?, ?> redisTemplate() {

    RedisTemplate<byte[], byte[]> template = new
RedisTemplate<byte[], byte[]>(); return template; } }


@Autowired PersonRepository repo;

public void basicCrudOperations() {

  Person rand = new Person("rand", "al'thor");
  rand.setAddress(new Address("emond's field", "andor"));
  // 如果rand的id值不存在,將會自動建立
  // 預設生成hash的key為keyspace:id樣式,例如persons:5d67b7e1-8640-4475-beeb-c666fab4c0e5
  repo.save(rand);                                         
  // 使用keyspace:id查詢資料
  repo.findOne(rand.getId());           

  repo.count();                                            
  repo.delete(rand);                                       
}

物件對映到Hash

上文的Peron物件將被用以下方式儲存到Redis的hash中
key值等於”persons:5d67b7e1-8640-4475-beeb-c666fab4c0e5”
field、value包括

_class = org.example.Person           
id = 5d67b7e1-8640-4475-beeb-c666fab4c0e5
firstname = rand                       
lastname = al’thor
address.city = emond's field          
address.country = andor

_class屬性為Redis實體的類名

複雜的型別屬性用點號分隔路徑

Java對映規則
簡單型別,如String

String firstname = “rand”;

對映為

firstname = “rand”

複合型別,如Address物件

Address adress = new Address(“emond’s field”);

對映為

address.city = “emond’s field”

List

List nicknames = asList(“dragon reborn”, “lews therin”);

對映為

nicknames.[0] = “dragon reborn”,
nicknames.[1] = “lews therin”

Map

Map

List複合型別

List

addresses = asList(new Address(“em…​

對映為

addresses.[0].city = “emond’s field”,
addresses.[1].city = “…​

Map複合型別

Map

自定義對映規則
Json對映


@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將生成下面的類似的filed和value

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


@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<Address, Map<String, byte[]>> {

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

使用上面的定製Converter將生成下面的類似的filed和value



_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
ciudad = "emond's field"

Keyspaces

Keyspaces定義字首用於建立Hash的key,預設使用在Redis實體的getClass().getName()。

可通過在Redis實體註解RedisHash 引數設定

@RedisHash("persons")
public class Person {

}

也可以在配置類中用EnableRedisRepositories設定。



@Configuration
@EnableRedisRepositories(keyspaceConfiguration = MyKeyspaceConfiguration.class)
public class ApplicationConfig {

  //... RedisConnectionFactory and RedisTemplate Bean definitions omitted

  public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {

    @Override
    protected Iterable<KeyspaceSettings> initialConfiguration() {
      return Collections.singleton(new KeyspaceSettings(Person.class, "persons"));
    }
  }
}

或者在配置類中編碼設定



@Configuration
@EnableRedisRepositories
public class ApplicationConfig {

  //... RedisConnectionFactory and RedisTemplate Bean definitions omitted

  @Bean
  public RedisMappingContext keyValueMappingContext() {
    return new RedisMappingContext(
      new MappingConfiguration(
        new MyKeyspaceConfiguration(), new IndexConfiguration()));
  }

  public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {

    @Override
    protected Iterable<KeyspaceSettings> initialConfiguration() {
      return Collections.singleton(new KeyspaceSettings(Person.class, "persons"));
    }
  }
}

索引

Redis對欄位的索引是通過

TTL