ValueOperations 操作接口定义了怎样操作 Redis 简单值(或 Redis 中的字符串)。在 RedisTemplate 中,可以通过 opsForValue() 方法获取该操作接口。代码如下:
ValueOperations<String,String> ops = redisTemplate.opsForValue()
通过 set 方法可以将指定的 key-value 值写入到 Redis,方法定义如下:
void set(K key, V value) 设置键的值。
void set(K key, V value, long offset) 用给定值从指定偏移量开始覆盖键的部分值。
void set(K key, V value, long timeout, TimeUnit unit) 设置键的值和过期时间。
Boolean setIfAbsent(K key, V value) 如果 key 不存在,则设置键的值。
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
// 设置 set-key1 到 redis
ops.set("set-key1", "hello world");
System.out.println("set-key1 = " + ops.get("set-key1"));
// 使用 12345 覆盖 set-key1 键中的 world 子字符串
ops.set("set-key1", "12345", 6);
System.out.println("set-key1 = " + ops.get("set-key1"));
// 设置 set-key2 过期时间为 20 秒
ops.set("set-key2", "hello", 20, TimeUnit.SECONDS);
System.out.println("set-key2 = " + ops.get("set-key2"));
// 如果 set-key3 不存在,则设置 set-key3 键
ops.setIfAbsent("set-key3", "value3-1");
System.out.println("set-key3 = " + ops.get("set-key3"));
ops.setIfAbsent("set-key3", "value3-2"); // 执行后无效果
System.out.println("set-key3 = " + ops.get("set-key3"));运行示例,输出结果:
set-key1 = hello world set-key1 = hello 12345 set-key2 = hello set-key3 = value3-1 set-key3 = value3-1
通过 get 方法可以从 redis 中获取指定键的值,方法定义如下:
String get(K key, long start, long end) 获取指定键,值的 start 和 end 之间的子字符串。
V get(Object key) 获取键的值。
V getAndSet(K key, V value) 设置键的值并返回其旧值。
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
// 设置 get-key1 到 redis
ops.set("get-key1", "hello world");
// 获取 get-key1 键的值
System.out.println(ops.get("get-key1"));
// 获取 get-key1 键的值的 6~11 子字符串
System.out.println(ops.get("get-key1", 6, 11));
// 设置新值且返回旧值
System.out.println(ops.getAndSet("get-key1", "new Value"));
System.out.println(ops.get("get-key1"));运行示例,输出结果:
hello world world hello world new Value
可以通过 setBit() 方法设置键对应值中某一个位(bit)的值为0或者1。然后,利用 getBit 方法获取键的值中某一位(bit)的值。方法定义如下:
Boolean getBit(K key, long offset) 获取键值偏移处的位值。
Boolean setBit(K key, long offset, boolean value) 设置键值偏移处的位置。
示例:使用 Redis 的 bit 位来实现判断 0~9、a-z、, 和 . 字符在输入的字符串是否出现。如果出现过,则输出到控制台。代码如下:
// 初始化数据,将指定偏移的位设置为0
char[] metaData = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', ',', '.'
};
ValueOperations<String,String> ops = redisTemplate.opsForValue();
for(int i = 0; i < metaData.length; i++) {
ops.setBit("metaData", metaData[i], false);
}
// 根据字符串,将指定偏移的位设置为1
String data = "haha.";
for(int i = 0; i < data.length(); i++) {
char ch = data.charAt(i);
ops.setBit("metaData", ch, true);
}
// 获取结果,哪些字母出现过,即位等于1对应的字母
for(int i = 0; i < metaData.length; i++) {
char ch = metaData[i];
Boolean val = ops.getBit("metaData", ch);
if(null != val && val) {
System.out.println(ch + " = " + val);
}
}运行示例,输出结果:
a = true h = true . = true
可以使用 append() 方法将给定的值追加到已存在值的后面。方法定义如下:
Integer append(K key, String value) 将指定的值追加到指定的键。
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
ops.set("append-key", "hello");
System.out.println("old: " + ops.get("append-key"));
// 将新值 “world” 追加到 “append-key” 后面
ops.append("append-key", "world");
System.out.println("new: " + ops.get("append-key"));
// 如果追加的键不存在,效果和 set 方法类似
ops.append("append-key2", "new value");
System.out.println(ops.get("append-key2"));运行示例,输出结果:
old: hello new: helloworld new value
使用 increment() 方法可以对指定键中的数字值进行递增,不需要使用 get() 取值,将值加n,再次将值写入 Redis。方法定义如下:
Double increment(K key, double delta) 将指定键存储的数字值添加delta。
Long increment(K key) 将指定键存储的数字值添加1。
Long increment(K key, long delta) 将指定键存储的数字值添加delta。
示例:分析一个字符串,使用 Redis 统计各个字母出现的次数。
char[] chars = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
// 初始化数据
ValueOperations<String,String> ops = redisTemplate.opsForValue();
for(char ch : chars) {
String key = "increment:" + ch;
ops.set(key, "0");
}
// 分析字符串中字母 a-z 各个字母出现的次数
String str = "Hello, welcome to the Spring Data Redis tutorial.";
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(Character.isLowerCase(ch)) {
String key = "increment:" + ch;
//ops.increment(key);
// 等价
ops.increment(key, 1);
}
}
// 输出结果
for(char ch : chars) {
String key = "increment:" + ch;
System.out.println(key + " = " + ops.get(key));
}运行示例,输出结果:
increment:a = 3 increment:b = 0 increment:c = 1 increment:d = 1 increment:e = 5 increment:f = 0 increment:g = 1 increment:h = 1 increment:i = 3 increment:j = 0 increment:k = 0 increment:l = 4 increment:m = 1 increment:n = 1 increment:o = 4 increment:p = 1 increment:q = 0 increment:r = 2 increment:s = 1 increment:t = 5 increment:u = 1 increment:v = 0 increment:w = 1 increment:x = 0 increment:y = 0 increment:z = 0
可以使用 ValueOperations 操作接口中 multi 前缀的方法实现批量操作,如:批量获取,批量设置等。方法定义如下:
List<V> multiGet(Collection<K> keys) 获取多个键的值
void multiSet(Map<? extends K,? extends V> map) 使用提供的 map 批量设置 key-value。
Boolean multiSetIfAbsent(Map<? extends K,? extends V> map) 使用提供的 map 批量设置 key-value,如果 key 存在,则设置。
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
// 批量写入值
Map<String,String> map1 = new HashMap<>();
map1.put("multi-key1", "value1");
map1.put("multi-key2", "value2");
map1.put("multi-key3", "value3");
ops.multiSet(map1);
// 写入失败,因为 multi-key3 已经存在
// 只要 map2 中有一个 key 存在,则整个 map 将不会被保存
Map<String,String> map2 = new HashMap<>();
map2.put("multi-key3", "value3-1");
map2.put("multi-key4", "value4");
ops.multiSetIfAbsent(map2);
// 写入成功,multi-key5 不存在
Map<String,String> map3 = new HashMap<>();
map3.put("multi-key5", "value5");
ops.multiSetIfAbsent(map3);
// 批量获取键的值
List<String> list = ops.multiGet(Arrays.asList(
"multi-key1", "multi-key2", "multi-key3",
"multi-key4", "multi-key5"));
for(String str : list) {
System.out.println(str);
}运行示例,输出结果:
value1 value2 value3 null value5
使用 size() 方法可以获取指定键存储值的大小,方法定义如下:
Long size(K key) 获取存储在键中的值的长度。
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
ops.set("size-key", UUID.randomUUID().toString());
System.out.println("value = " + ops.get("size-key"));
Long size = ops.size("size-key");
System.out.println("size = " + size);运行示例,输出结果:
value = 25ca189b-8f1c-493d-ae67-420d1e2d6535 size = 36
RedisOperations 接口定义了一组 Redis 基本操作,由 RedisTemplate 类去实现。在 ValueOperations 中,可以通过 getOperations() 方法获取 RedisTemplate 的实例。方法定义如下:
RedisOperations<K,V> getOperations()
示例:
ValueOperations<String,String> ops = redisTemplate.opsForValue();
RedisOperations<String,String> redisOperations = ops.getOperations();
System.out.println("redisOperations = " + redisOperations);
System.out.println(" redisTemplate = " + redisTemplate);运行示例,输出结果:
redisOperations = org.springframework.data.redis.core.RedisTemplate@5c53f292 redisTemplate = org.springframework.data.redis.core.RedisTemplate@5c53f292
从上结果可知,getOperations() 方法返回的实际就是我们通过 opsForValue() 方法取得 ValueOperations 对象的 RedisTemplate 实例。