Redis的Strings命令
相关命令
- APPEND
- BITCOUNT
- BITFIELD
- BITOP
- BITPOS
- DECR
- DECRBY
- GET
- GETBIT
- GETRANGE
- GETSET
- INCR
- INCRBY
- INCRBYFLOAT
- MGET
- MSET
- MSETNX
- PSETEX
- SET
- SETBIT
- SETEX
- SETNX
- SETRANGE
- STRLEN
定义redisTemplate
@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); } }