Redis에서 데이터는 여러 형태의 데이터 구조로 저장될 수 있다.
객체는 Jackson2JsonRedisSerializer
를 통해 JSON 문자열로 변환될 수 있는데, Redis 해시를 사용한다면 정교한 매핑이 가능하다.
일반적인 JSON 형식이 한 키에 한 값이 매핑되는 구조를 띈다면
Redis 해시를 활용했을 땐, 한 키에 여러 값을 매핑할 수 있다.
Spring Data Redis는 해시에 데이터를 매핑할 수 있는 3가지의 전략을 제공한다.
HashOperations
와 Serializer
를 이용한 직접적인 매핑HashMapper
와 HashOperations
활용HashMapper
는 객체와 Map<K, V>
사이의 변환을 이뤄낸다.
public class Person {
String firstname;
String lastname;
// …
}
public class HashMapping {
@Resource(name = "redisTemplate")
HashOperations<String, byte[], byte[]> hashOperations;
HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper();
public void writeHash(String key, Person person) {
Map<byte[], byte[]> mappedHash = mapper.toHash(person);
hashOperations.putAll(key, mappedHash);
}
public Person loadHash(String key) {
Map<byte[], byte[]> loadedHash = hashOperations.entries(key);
return (Person) mapper.fromHash(loadedHash);
}
}
위 코드에서 Person
객체를 Map<byte[], byte[]>
로 변환하는 것처럼 객체를 Map
으로 변환시켜 Redis에 저장하는 역할로 사용된다.
관련된 구현체 종류는 아래와 같다
BeanUtils
를 사용하는 BeanUtilsHashMapper
ObjectHashMapper
Jackson2HashMapper
Jackson2HashMapper
는 최상위 속성들을 해시 필드이름으로 매핑한다.
클래스 타입의 필드는 중첩된 JSON 구조로 표현되지만, 원한다면 각 속성에 대한 개별해시 항목으로 변환하는 것도 가능하다.
public class Person {
String firstname;
String lastname;
Address address;
Date date;
LocalDateTime localDateTime;
}
public class Address {
String city;
String country;
}
예를들어, 위 클래스 구조에서 Person
을 JSON으로 변환한다고 가정해보자.
Hash 필드 | 값 |
---|---|
firstname | Jon |
lastname | Snow |
address | { "city" : "Castle Black", "country" : "The North" } |
date | 1561543964015 |
localDateTime | 2018-01-02T12:13:14 |
일반적인 변환은 위 구조로 이루어진다.
중첩 JSON을 이용하여 Address
객체가 표현되는 모습이다.
Hash 필드 | 값 |
---|---|
firstname | Jon |
lastname | Snow |
address.city | Castle Black |
address.country | The North |
date | 1561543964015 |
localDateTime | 2018-01-02T12:13:14 |
설정에 따라 위 형태처럼 Address
의 각 속성들을 개별 필드로 구성하는 것이 가능하다.
단, 이 구조에서 속성이름은 JSON 경로를 방해하지 않아야한다.
예를들어, 괄호나
.
이 속성이름에 들어가선 안된다.
임의로 해당 요소들이 들어간다면 다시 객체로 복원할 수 없다.