Redis的Strings命令

相关命令

 

定义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);
    }
}

 

posted @ 2019-09-16 17:51  门罗的魔术师  阅读(802)  评论(0编辑  收藏  举报