👀Redis 的 Hash 映射
在 Redis 中,哈希是一个字符串字段和字符串值之间的映射。它特别适合存储对象。Spring Data Redis 提供了多种方法来处理 Redis 哈希,下面我们会详细讨论。
✌1. 通过使用 HashOperations
和一个 serializer 直接映射
✍ 作用:
允许你使用 Redis 的哈希数据结构,直接存储、更新、删除和读取对象。
✍ 使用场景:
当你想要直接与 Redis 哈希交互,而不需要复杂的对象映射时。
✍ 优点:
- 简单直接。
- 可以使用自定义的 serializer。
✍ 缺点:
- 需要手动处理序列化和反序列化。
- 对于复杂的对象,可能需要更多的手动管理。
✍ 示例代码:
@Service
public class RedisHashService {
@Autowired
private StringRedisTemplate redisTemplate;
public void saveUser(User user) {
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
hashOps.put("user:" + user.getId(), "name", user.getName());
hashOps.put("user:" + user.getId(), "age", String.valueOf(user.getAge()));
}
public User getUser(String userId) {
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
Map<String, String> entries = hashOps.entries("user:" + userId);
User user = new User();
user.setId(userId);
user.setName(entries.get("name"));
user.setAge(Integer.parseInt(entries.get("age")));
return user;
}
}
✌2. 使用 Redis Repository
✍ 作用:
提供了一种类似于 JPA 的方式来管理 Redis 哈希数据。
✍ 使用场景:
当你希望使用更高级的、声明性的方式来管理 Redis 数据时。
✍ 优点:
- 更高级的抽象。
- 与 Spring Data JPA 类似的编程模型。
✍ 缺点:
- 需要更多的配置。
- 可能不是最高效的方法,特别是对于大量的数据操作。
✍ 示例代码:
// Entity
@RedisHash("user")
public class User {
@Id
private String id;
private String name;
private int age;
// getters and setters
}
// Repository
public interface UserRepository extends CrudRepository<User, String> {
}
// Service
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.save(user);
}
public User getUser(String userId) {
return userRepository.findById(userId).orElse(null);
}
}
✌3. 使用 HashMapper
和 HashOperations
HashMapper
提供了一种将对象映射到 Redis 哈希和从 Redis 哈希映射回对象的方法。
✍ a. BeanUtilsHashMapper
使用 Spring 的 BeanUtils
.
🎯 作用:
允许使用 Spring 的 BeanUtils 将 Java beans 映射到 Redis 哈希和反向映射。
🎯 使用场景:
当你的对象与 Redis 哈希有一对一的映射,并且你想要一个简单的方式来转换它们时。
🎯 优点:
- 简单且易于使用。
- 无需额外的配置或注解。
🎯 缺点:
- 不适合复杂的对象结构。
- 仅支持简单的数据类型。
🎯 示例代码:
@Service
public class UserServiceWithBeanUtils {
@Autowired
private StringRedisTemplate redisTemplate;
private final HashMapper<User, String, String> mapper = new BeanUtilsHashMapper<>(User.class);
public void saveUser(User user) {
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
Map<String, String> mappedHash = mapper.toHash(user);
hashOps.putAll("user:" + user.getId(), mappedHash);
}
public User getUser(String userId) {
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
Map<String, String> loadedHash = hashOps.entries("user:" + userId);
return mapper.fromHash(loadedHash);
}
}
✍ b. ObjectHashMapper
使用 对象(Object)到哈希的映射.
- 描述:这是Spring Data Redis的官方文档,其中详细描述了ObjectHashMapper的API。
- 使用场景:当你需要在Spring Boot项目中使用Redis作为缓存或数据存储时,可以使用ObjectHashMapper来将Java对象映射到Redis的哈希数据结构。
- 优点:提供了与Spring集成的简单方法,支持嵌套属性和简单类型,如String。
- 缺点:需要对Spring Data Redis有一定的了解。
@Bean
public HashMapper<Object, byte[], byte[]> hashMapper() {
return new ObjectHashMapper();
}
@Component
public class HashMapping<T> {
@NonNull
private StringRedisTemplate stringRedisTemplate;
@NonNull
private HashMapper<Object, byte[], byte[]> hashMapper;
public void writeHash(String key, T t) {
checkNotNull(key, "hash key cannot be null");
checkNotNull(t, "hash value cannot be null");
stringRedisTemplate.execute((RedisCallback<Void>) connection -> {
Map<byte[], byte[]> mappedHash = hashMapper.toHash(t);
connection.hMSet(key.getBytes(), mappedHash);
return null;
});
}
public T loadHash(String key) {
checkNotNull(key, "hash key cannot be null");
Map<byte[], byte[]> loadedHash = stringRedisTemplate.getConnectionFactory().getConnection().hGetAll(key.getBytes());
return (T) hashMapper.fromHash(loadedHash);
}
}
✍ c. Jackson2HashMapper
🎯 作用:
提供了使用 Jackson 库将对象映射到 Redis 哈希的方法。
🎯 使用场景:
当你想要使用 JSON 格式存储对象,并希望能够轻松地将对象映射到 Redis 哈希时。
🎯 优点:
- 利用 Jackson 的强大功能。
- 可以处理更复杂的对象结构。
🎯 缺点:
- 需要 Jackson 依赖。
- 可能不如其他简单映射器那么高效。
🎯 示例代码:
@Service
public class UserServiceWithJackson {
@Autowired
private StringRedisTemplate redisTemplate;
private final HashMapper<Object, byte[], byte[]> mapper = new Jackson2HashMapper(false);
public void saveUser(User user) {
HashOperations<String, byte[], byte[]> hashOps = redisTemplate.opsForHash();
Map<byte[], byte[]> mappedHash = mapper.toHash(user);
hashOps.putAll("user:" + user.getId(), mappedHash);
}
public User getUser(String userId) {
HashOperations<String, byte[], byte[]> hashOps = redisTemplate.opsForHash();
Map<byte[], byte[]> loadedHash = hashOps.entries("user:" + userId);
return (User) mapper.fromHash(loadedHash);
}
}
总结:Spring Data Redis 提供了多种方法来处理和管理 Redis 的哈希数据结构,从简单的直接操作到更复杂的对象映射方法。选择哪种方法取决于你的具体需求和偏好。