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 实例。