redis基础学习

1. 概述

1.1 什么是redis

一款基于c语言实现的高性能的非关系型数据库;
提供了五种数据类型,致力于使用数据结构帮助用户解决问题;

1.2 redis的使用场景

1.3 redis为什么快

1.完全基于内存;
2.单线程,无需考虑线程切换;
3.NIO ,io复用模型;
4.非关系型数据库;

2. 基本数据类型

redis有五种数据类型;
在这里插入图片描述
通用代码:

@Autowired
    private RedisTemplate redisTemplate;
    //通用1 给key设置失效时间
    public void setKeyTime(String key,int time){
        //一可死败儿
        redisTemplate.expire(key,time, TimeUnit.SECONDS);
    }
    //通用2 获取key的失效时间
    public void KeyTime(String key){
        //一可死败儿
        redisTemplate.getExpire(key);
    }
    //通用3 判断key是否存在
    public boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }
    //通用4 删除key
    public void del(String[] keyArray){
            redisTemplate.delete(keyArray);
    }

2.1 Stirng的使用(opsForValue)

redisTemplate.opsForValue()方法;
注意:使用increment方法时要注意序列化问题,如果value被序列化则无法使用爆出:
ERR value is not an integer or out of range

    @RequestMapping(value ="/anon/getStirng", method = RequestMethod.GET)
    //获取Stirng
    public String getStirng(String key){
        return (String) redisTemplate.opsForValue().get(key);
    }
    //设置Stirng
    @RequestMapping(value = "/anon/setStirng",method = RequestMethod.GET)
    public void SetStirng(String key,String value){
        redisTemplate.opsForValue().set(key,value);
    }
    //设置String 并添加过期时间
    @RequestMapping(value = "/anon/setStirngAndTime",method = RequestMethod.GET)
    public void setStirngAndTime(String key,String value,int time){
        redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
    }
    //递增 存进去的值得是int对应类型的
    @RequestMapping(value = "/anon/incr",method = RequestMethod.GET)
    public Long incr(Long data){
        if (!redisTemplate.hasKey("incrKey"))
        stringRedisTemplate.opsForValue().set("incrKey", String.valueOf(1));
        return stringRedisTemplate.opsForValue().increment("incrKey", data);
    }
    //递减少 存进去的值得是int对应类型的
    @RequestMapping(value = "/anon/incr2",method = RequestMethod.GET)
    public Long incr2(String key,Long data){
        return redisTemplate.opsForValue().increment(key, -data);
    }

2.2 List的使用

redisTemplate.opsForList方法()

//  插入List
    public void lSet(String key, List<Object> value) {
          redisTemplate.opsForList().rightPushAll(key, value);
    }
//  插入并指定过期时间
    public void lSetAndTime(String key, List<Object> value,int time) {
        redisTemplate.opsForList().rightPushAll(key, value,time,TimeUnit.SECONDS);
    }
//  获取list内容
    @RequestMapping(value = "/anon/lget",method = RequestMethod.GET)
    public List lget(String key,int start,int end) {
        if (!redisTemplate.hasKey(key)){
            ArrayList<Object> objects = new ArrayList<>();
            objects.add("1");
            objects.add("2");
            redisTemplate.opsForList().rightPushAll(key,objects);
        }

        return redisTemplate.opsForList().range(key, start, end);
    }
//  获取list长度
    public Long lgetSize(String key) {
        return redisTemplate.opsForList().size(key);
    }
//  移除N个值为value
    public void lRemove(String key,int count,String value){
        redisTemplate.opsForList().remove(key,count,value);
    }

2.3 set的使用

opsforSet();

//  添加一个set缓存
    public long sSet(String key, Object...values) {
            return redisTemplate.opsForSet().add(key, values);
    }
//  添加一个set缓存2
    public long sSet2(String key, String[] Array) {
        return redisTemplate.opsForSet().add(key, Array);
    }
//  获取值
    public Set sGet(String key) {
        return redisTemplate.opsForSet().members(key);
    }
//  判断set中包含某个值
    public boolean hasSet(String key ,String value){
        return redisTemplate.opsForSet().isMember(key,value);

    }
//  移除set中包含某个值
    public long hasSet(String key ,String...value){
        return redisTemplate.opsForSet().remove(key,value);
    }

2.3 Hash的使用

3. redis分布式锁

分布式锁注意的两个问题:
1.加锁的时候注意指定过期时间,如果不指定,那么一旦加锁的线程挂掉将会导致锁不会被释放;
2.加了过期时间可能会出现,在加锁期间内任务没有完成锁就被释放;所以需要一条守护线程进行续命;

加锁:加锁的时间使用的是当前时间+加锁时间,不是过期策略,比如加锁300ms,但是1s过去了锁还在,其他人想加锁进来自己判断加锁是否过期,过期则重新加锁否则加锁失败;

    /**
     * 最终加强分布式锁
     * @param key key值
     * @return 是否获取到
     */
public boolean lock(String key) {
        String lock = LOCK_PREFIX + key;
        // 利用lambda表达式
        return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
                Boolean acquire = redisConnection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
                if (acquire) {
                    return true;
                } else {
                    byte[] value = redisConnection.get(lock.getBytes());
                    if (Objects.nonNull(value) && value.length > 0) {
                        long expireTime = Long.parseLong(new String(value));
                        if (expireTime < System.currentTimeMillis()) {
                            // 如果锁已经过期
                            byte[] oldValue = redisConnection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
                            // 防止死锁
                            return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
                        }
                    }
                }
                return false;
            }
        });
    }

解锁:

    /**
     * 删除锁
     *
     * @param key
     */
    public void delete(String key) {
        redisTemplate.delete(key);
    }

4. redis事务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值