@Bean
RedisTemplate<String,Integer> redisIntegerTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<String,Integer> template = new RedisTemplate<String,Integer>();
template.setConnectionFactory(connectionFactory);
//return template;
// 3.创建 序列化类
GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Integer.class);
// 6.序列化类,对象映射设置
// 7.设置 value 的转化格式和 key 的转化格式
template.setValueSerializer(genericToStringSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
spring的对应代码
package com.example.redistest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class RedisTestService {
@Autowired
RedisTemplate<String,String> redisTemplate;
@Autowired
RedisTemplate<String,Integer> redisIntegerTemplate;
public void stringsTest(){
//appendString();
//bitTest();
//decrAndIncrTest();
//getRange();
//getSet();
//multiOperate();
set();
* APPEND key value
* 如果 key 已经存在,并且值为字符串,那么这个命令会把 value 追加到原来值(value)的结尾。
* 如果 key 不存在,那么它将首先创建一个空字符串的key,再执行追加操作,这种情况 APPEND 将类似于 SET 操作。
public void appendString(){
for(int i=0;i<20;i++) {
redisTemplate.opsForValue().append("appendString", "0");
String value = redisTemplate.opsForValue().get("appendString");
System.out.println("1. APPEND:" + value);
redisTemplate.delete("appendString");
* SETBIT key offset value
* 设置或者清空key的value(字符串)在offset处的bit值。
* 那个位置的bit要么被设置,要么被清空,这个由value(只能是0或者1)来决定。
* 当key不存在的时候,就创建一个新的字符串value。
* 要确保这个字符串大到在offset处有bit值。
* 参数offset需要大于等于0,并且小于232(限制bitmap大小为512)。
* 当key对应的字符串增大的时候,新增的部分bit值都是设置为0。
* 警告:当set最后一个bit(offset等于232-1)并且key还没有一个字符串value或者其value是个比较小的字符串时,
* Redis需要立即分配所有内存,这有可能会导致服务阻塞一会。
* 在一台2010MacBook Pro上,offset为232-1(分配512MB)需要~300ms,offset为230-1(分配128MB)需要~80ms,
* offset为228-1(分配32MB)需要~30ms,offset为226-1(分配8MB)需要8ms。
* 注意,一旦第一次内存分配完,后面对同一个key调用SETBIT就不会预先得到内存分配。
* GETBIT key offset
* 返回key对应的string在offset处的bit值 当offset超出了字符串长度的时候,这个字符串就被假定为由0比特填充的连续空间。
* 当key不存在的时候,它就认为是一个空字符串,所以offset总是超出范围,然后value也被认为是由0比特填充的连续空间。到内存分配。
* BITCOUNT key [start end]
* 统计字符串被设置为1的bit数.
* 一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。
* start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:
* 比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。
* 不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。
public void bitTest(){
redisTemplate.opsForValue().setBit("bitTest", 10,true);
redisTemplate.opsForValue().setBit("bitTest", 100,true);
redisTemplate.opsForValue().setBit("bitTest", 200,true);
Boolean boolvalue = redisTemplate.opsForValue().getBit("bitTest", 10);
System.out.println("2.1 getbit 10 boolvalue:" + boolvalue);
boolvalue = redisTemplate.opsForValue().getBit("bitTest", 100);
System.out.println("2.1 getbit 100 boolvalue:" + boolvalue);
boolvalue = redisTemplate.opsForValue().getBit("bitTest", 200);
System.out.println("2.1 getbit 200 boolvalue:" + boolvalue);
boolvalue = redisTemplate.opsForValue().getBit("bitTest", 300);
System.out.println("2.1 getbit 300 boolvalue:" + boolvalue);
/* for(int i=0;i<300;i++){
boolvalue = redisTemplate.opsForValue().getBit("bitTest", i);
System.out.println("2. getbit " + i + " boolvalue:" + boolvalue);
/* BitFieldSubCommands.BitFieldSubCommand bitFieldSubCommand = new BitFieldSubCommands.AbstractBitFieldSubCommand() {
@Override
public String getCommand() {
return "";
BitFieldSubCommands fieldSubCommands = BitFieldSubCommands.create();
List<Long> a = redisTemplate.opsForValue().bitField("bitTest",fieldSubCommands);
System.out.println("2.2 bitCount:" + a.size());
RedisOperations<String,String> a1 = redisTemplate.opsForValue().getOperations();*/
redisTemplate.delete("bitTest");
* DECR key
* 对key对应的数字做减1操作。如果key不存在,那么在操作之前,这个key对应的值会被置为0。
* 如果key有一个错误类型的value或者是一个不能表示成数字的字符串,就返回错误。这个操作最大支持在64位有符号的整型数字。
* 查看命令INCR了解关于增减操作的额外信息。
* DECRBY key decrement
* 将key对应的数字减decrement。如果key不存在,操作之前,key就会被置为0。
* 如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的正型数字。
* 查看命令INCR了解关于增减操作的额外信息。似。
* INCR key
* 对存储在指定key的数值执行原子的加1操作。
* 如果指定的key不存在,那么在执行incr操作之前,会先将它的值设定为0。
* 如果指定的key中存储的值不是字符串类型(fix:)或者存储的字符串类型不能表示为一个整数,
* 那么执行这个命令时服务器会返回一个错误(eq:(error) ERR value is not an integer or out of range)。
* 这个操作仅限于64位的有符号整型数据。
* INCRBY key increment
* 将key对应的数字加decrement。如果key不存在,操作之前,key就会被置为0。
* 如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的正型数字。
* 查看命令INCR了解关于增减操作的额外信息。
* INCRBYFLOAT key increment
* 通过指定浮点数key来增长浮点数(存放于string中)的值. 当键不存在时,先将其值设为0再操作.下面任一情况都会返回错误:
* key 包含非法值(不是一个string).
* 当前的key或者相加后的值不能解析为一个双精度的浮点值.(超出精度范围了)
* 如果操作命令成功, 相加后的值将替换原值存储在对应的键值上, 并以string的类型返回.
* string中已存的值或者相加参数可以任意选用指数符号,但相加计算的结果会以科学计数法的格式存储.
* 无论各计算的内部精度如何, 输出精度都固定为小数点后17位.
* 返回值
* Bulk-string-reply: 当前key增加increment后的值。
public void decrAndIncrTest(){
//redisIntegerTemplate.delete("decrAndIncrTest");
redisIntegerTemplate.opsForValue().set("decrAndIncrTest",0);
Long value = redisIntegerTemplate.opsForValue().increment("decrAndIncrTest");
System.out.println("3 decrAndIncrTest increment 1:" + value);
value = redisIntegerTemplate.opsForValue().increment("decrAndIncrTest",2);
System.out.println("3 decrAndIncrTest increment 3:" + value);
value = redisIntegerTemplate.opsForValue().decrement("decrAndIncrTest");
System.out.println("3 decrAndIncrTest decrement 2:" + value);
value = redisIntegerTemplate.opsForValue().decrement("decrAndIncrTest",10);
System.out.println("3 decrAndIncrTest decrement -8:" + value);
Double douVal = redisIntegerTemplate.opsForValue().increment("decrAndIncrTest",2.12);
System.out.println("3 decrAndIncrTest increment -5.88:" + douVal);
redisIntegerTemplate.delete("decrAndIncrTest");
* GETRANGE key start end
* 警告:这个命令是被改成GETRANGE的,在小于2.0的Redis版本中叫SUBSTR。
* 返回key对应的字符串value的子串,这个子串是由start和end位移决定的(两者都在string内)。
* 可以用负的位移来表示从string尾部开始数的下标。所以-1就是最后一个字符,-2就是倒数第二个,以此类推。
* 这个函数处理超出范围的请求时,都把结果限制在string内。
public void getRange(){
redisTemplate.opsForValue().set("getRange","0123456789abcdefg");
String value = redisTemplate.opsForValue().get("getRange",0,-1);
System.out.println("4 getRange 0~-1:" + value);
value = redisTemplate.opsForValue().get("getRange",0,5);
System.out.println("4 getRange 0~5:" + value);
redisTemplate.delete("getRange");
* GETSET key value
* 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串,就返回错误。
public void getSet(){
Integer a = redisIntegerTemplate.opsForValue().getAndSet("getAndSet",0);
System.out.println("4 getSet:" + a);
Long l = redisIntegerTemplate.opsForValue().increment("getAndSet");
System.out.println("4 increment:" + l);
l = redisIntegerTemplate.opsForValue().increment("getAndSet");
System.out.println("4 increment:" + l);
a = redisIntegerTemplate.opsForValue().getAndSet("getAndSet",0);
System.out.println("4 getSet:" + a);
redisIntegerTemplate.delete("getAndSet");
* MGET key [key ...]
* 返回所有指定的key的value。对于每个不对应string或者不存在的key,都返回特殊值nil。正因为此,这个操作从来不会失败。
* MSET key value [key value ...]
* 对应给定的keys到他们相应的values上。MSET会用新的value替换已经存在的value,就像普通的SET命令一样。
* 如果你不想覆盖已经存在的values,请参看命令MSETNX。
* MSET是原子的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
* MSETNX key value [key value ...]
* 对应给定的keys到他们相应的values上。只要有一个key已经存在,MSETNX一个操作都不会执行。
* 由于这种特性,MSETNX可以实现要么所有的操作都成功,要么一个都不执行,这样可以用来设置不同的key,来表示一个唯一的对象的不同字段。
* MSETNX是原子的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
* SETEX key seconds value
public void multiOperate(){
redisIntegerTemplate.delete("key1");
redisIntegerTemplate.delete("key2");
redisIntegerTemplate.delete("key3");
//redisIntegerTemplate.opsForValue().set("key3",6);
Map<String,Integer> map = new HashMap<>();
map.put("key1",1);
map.put("key2",2);
map.put("key3",3);
//redisIntegerTemplate.opsForValue().multiSet(map);
Boolean bool = redisIntegerTemplate.opsForValue().multiSetIfAbsent(map);
System.out.println("multiSetIfAbsent:" + bool);
List<String> keys = new ArrayList<>();
keys.add("key1");
keys.add("key2");
keys.add("key3");
List<Integer> list = redisIntegerTemplate.opsForValue().multiGet(keys);
for(int i= 0;i < list.size();i++){
System.out.println("key" + (i+1) + ",value:" + list.get(i));
redisIntegerTemplate.delete("key1");
redisIntegerTemplate.delete("key2");
redisIntegerTemplate.delete("key3");
* SETRANGE key offset value
* 这个命令的作用是覆盖key对应的string的一部分,从指定的offset处开始,覆盖value的长度。
* 如果offset比当前key对应string还要长,那这个string后面就补0以达到offset。
* 不存在的keys被认为是空字符串,所以这个命令可以确保key有一个足够大的字符串,能在offset处设置value。
* SETEX key seconds value
* 设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期。这个命令等效于执行下面的命令:
* SET mykey value
* EXPIRE mykey seconds
* SETEX是原子的,也可以通过把上面两个命令放到MULTI/EXEC块中执行的方式重现。
* 相比连续执行上面两个命令,它更快,因为当Redis当做缓存使用时,这个操作更加常用。
* STRLEN key
* 返回key的string类型value的长度。如果key对应的非string类型,就返回错误。
public void set(){
redisTemplate.delete("set");
redisTemplate.opsForValue().set("set","123");
//对应SETRANGE
redisTemplate.opsForValue().set("set","abcd",100);
String value = redisTemplate.opsForValue().get("set");
System.out.println("set:" + value);
//100秒
//对应SETEX 3333 100
redisTemplate.opsForValue().set("set","3333",100,TimeUnit.SECONDS);
//300秒
//对应SETEX 222 300
redisTemplate.opsForValue().set("set","222",Duration.ofSeconds(300));
//对应STRLEN key
Long size = redisTemplate.opsForValue().size("set");
System.out.println("对应STRLEN:" + size);