大多数用户可能会使用 RedisTemplate 及其相应的包,org.springframework.data.redis.core。事实上,template 是Redis模块的中心类,由于其丰富的功能集。该template为Redis的交互提供了一个高层次的抽象。RedisConnection 提供了接受和返回二进制值(byte 数组)的低级方法,模板负责序列化和连接管理,将用户从处理这些细节中解放出来。
此外,模板还提供了操作视图(operations view)(遵循Redis命令 参考 中的分组),这些视图提供了丰富的、生成的接口,用于针对某种类型或某种key(通过 KeyBound 接口)进行操作,如下表所述。
Key 类型的操作:
操作名称 | 作用 | 使用场景 |
---|---|---|
GeoOperations | Redis 的 geospatial 操作。 | 存储和查询地理位置信息,例如查询两点之间的距离。 |
HashOperations | 操作 Redis 的哈希数据结构。 | 存储对象或字典样的数据。 |
HyperLogLogOperations | Redis 的 HyperLogLog 操作。 | 进行基数估计,例如统计独立访客数量。 |
ListOperations | 操作 Redis 的列表数据结构。 | 存储有序的元素列表。 |
SetOperations | 操作 Redis 的集合数据结构。 | 存储不重复的值。 |
ValueOperations | 操作 Redis 的字符串或值。 | 存储简单的 key-value 数据。 |
ZSetOperations | 操作 Redis 的有序集合。 | 根据分数对值进行排序。 |
Key 绑定 操作:
操作名称 | 作用 | 使用场景 |
---|---|---|
BoundGeoOperations | Redis geospatial key 绑定操作。 | 对单个地理空间 key 执行多个操作。 |
BoundHashOperations | Redis hash key 绑定操作。 | 对单个哈希 key 执行多个操作。 |
BoundKeyOperations | Redis key 绑定操作。 | 对单一 key 执行多个常规操作。 |
BoundListOperations | Redis list key 绑定操作。 | 对单一列表 key 执行多个操作。 |
BoundSetOperations | Redis set key 绑定操作。 | 对单一集合 key 执行多个操作。 |
BoundValueOperations | Redis string (or value) key 绑定操作。 | 对单一键值对进行操作。 |
BoundZSetOperations | Redis zset (or sorted set) key 绑定操作。 | 对单一有序集合 key 执行多个操作。 |
@Configuration
class MyConfig {
@Bean
LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
public class Example {
// inject the actual template
@Autowired
private RedisTemplate<String, String> template;
// inject the template as ListOperations
@Resource(name="redisTemplate")
private ListOperations<String, String> listOps;
public void addLink(String userId, URL url) {
listOps.leftPush(userId, url.toExternalForm());
}
}
@Autowired
private GeoOperations<String, String> geoOps;
public void addLocation(String key, Point point, String member) {
geoOps.geoAdd(key, point, member);
}
@Autowired
private HashOperations<String, String, Object> hashOps;
public void addToHash(String key, String field, Object value) {
hashOps.put(key, field, value);
}
@Autowired
private HyperLogLogOperations<String, String> hllOps;
public void addToHLL(String key, String... values) {
hllOps.add(key, values);
}
@Autowired
private ListOperations<String, String> listOps;
public void addToList(String key, String value) {
listOps.leftPush(key, value);
}
@Autowired
private SetOperations<String, String> setOps;
public void addToSet(String key, String value) {
setOps.add(key, value);
}
@Autowired
private ValueOperations<String, String> valueOps;
public void setKeyValue(String key, String value) {
valueOps.set(key, value);
}
@Autowired
private ZSetOperations<String, String> zSetOps;
public void addToZSet(String key, String value, double score) {
zSetOps.add(key, value, score);
}
这些操作提供了一种绑定到特定 key 的方法,使得操作更为简洁。例如,对于绑定操作,你不需要为每个操作提供 key,因为 key 已经预先绑定。
BoundGeoOperations<String, String> boundGeoOps = redisTemplate.boundGeoOps("locationKey");
boundGeoOps.geoAdd(new Point(13.361, 38.115), "loc1");
BoundHashOperations<String, String, Object> boundHashOps = redisTemplate.boundHashOps("hashKey");
boundHashOps.put("field1", "value1");
BoundKeyOperations<String> boundKeyOps = redisTemplate.boundValueOps("sampleKey");
boundKeyOps.expire(10, TimeUnit.SECONDS);
BoundListOperations<String, String> boundListOps = redisTemplate.boundListOps("listKey");
boundListOps.leftPush("value1");
BoundSetOperations<String, String> boundSetOps = redisTemplate.boundSetOps("setKey");
boundSetOps.add("member1");
BoundValueOperations<String, String> boundValueOps = redisTemplate.boundValueOps("valueKey");
boundValueOps.set("newValue");
BoundZSetOperations<String, String> boundZSetOps = redisTemplate.boundZSetOps("zsetKey");
boundZSetOps.add("member1", 1.0);
这些“绑定操作”提供了一种直接方式在特定 key 上执行操作,使代码更简洁,因为不需要为每个操作提供 key 参数。
作用:保存文本或二进制数据。
使用场景:常规的键值存储,如保存配置、用户会话等。
示例代码:
@Autowired
private StringRedisTemplate stringRedisTemplate;
public void saveStringValue() {
stringRedisTemplate.opsForValue().set("key", "value");
}
public String getStringValue() {
return stringRedisTemplate.opsForValue().get("key");
}
作用:有序集合,可以在两端进行插入或删除。
使用场景:实现堆栈、队列、最近浏览的项目等。
示例代码:
@Autowired
private RedisTemplate<String, String> redisTemplate;
public void pushToList() {
redisTemplate.opsForList().leftPush("listKey", "value");
}
public String popFromList() {
return redisTemplate.opsForList().leftPop("listKey");
}
作用:无序的字符串集合,不允许重复。
使用场景:存储无序的唯一数据,如标签、关键字等。
示例代码:
public void addToSet() {
redisTemplate.opsForSet().add("setKey", "value1", "value2");
}
public boolean checkIfSetValueExists() {
return redisTemplate.opsForSet().isMember("setKey", "value1");
}
作用:键值对的集合,是字符串到字符串的映射。
使用场景:存储对象或数据实体。
示例代码:
public void saveToHash() {
redisTemplate.opsForHash().put("hashKey", "field", "value");
}
public Object getFromHash() {
return redisTemplate.opsForHash().get("hashKey", "field");
}
作用:使用位来存储数据,每个位的值只能是 0 或 1。
使用场景:统计、实时分析等,如跟踪用户登录或记录用户活动。
示例代码:
public void setBitValue() {
redisTemplate.opsForValue().setBit("bitmapKey", 1, true);
}
public Boolean getBitValue() {
return redisTemplate.opsForValue().getBit("bitmapKey", 1);
}
作用:用于估计唯一值的数量。
使用场景:当精确值不重要,但内存使用效率很重要时,如统计网站的独立访客数。
示例代码:(注意:Spring Data Redis 的接口不直接支持 HyperLogLog,但可以使用原始 Redis 命令来操作它)
与直接使用 Jedis 或 Lettuce 相比,Spring Data Redis 提供了一个更加直观和简化的 API。例如,你可以使用 RedisTemplate
或继承 CrudRepository
的接口来操作 Redis。
RedisTemplate
RedisTemplate
提供了一种高级方式来与 Redis 进行交互。它处理了底层的连接管理、资源释放、异常处理等,同时提供了直观的操作 API。
@Autowired
private RedisTemplate<String, String> redisTemplate;
public void setAndGet() {
redisTemplate.opsForValue().set("key", "value");
String value = redisTemplate.opsForValue().get("key");
}
CrudRepository
Spring Data Redis 提供了对 Spring Data 的支持,允许你定义继承 CrudRepository
的接口,自动实现基于 Redis 的 CRUD 操作。
@Entity
public class Person {
@Id
private String id;
private String name;
// ... getters and setters
}
public interface PersonRepository extends CrudRepository<Person, String> {
List<Person> findByName(String name);
}
@Service
public class PersonService {
@Autowired
private PersonRepository personRepository;
public Person savePerson(Person person) {
return personRepository.save(person);
}
public List<Person> findByName(String name) {
return personRepository.findByName(name);
}
}
总的来说,Spring Data Redis 提供了一套简化的 API,使得与 Redis 的交互更加直观和简洁。这些高级特性使得开发者可以更专注于业务逻辑,而不是底层的细节。