全网最详细高质量Redis入门教程(学不会算我输)

本文介绍了Redis的基础知识,包括NoSQL的特点、Redis的ACID特性、安装方法以及基本操作如字符串、列表、集合、哈希的操作。还讲解了Java通过Jedis库与Redis的交互,以及SpringBoot中整合Redis的配置和使用。此外,提到了Redis的持久化和密码设置。
摘要由CSDN通过智能技术生成

何夜息随笔录-Redis教程

NoSQL概述

什么是NoSQL?NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",它是泛指非关系型的数据库。

首先说关系型数据库:

关系型数据库遵循ACID规则

  1. A (Atomicity) 原子性

    原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。

  2. C (Consistency) 一致性

    一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

  3. I (Isolation) 独立性

    所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。

    比如现在有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。

  4. D (Durability) 持久性

    持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

NoSQL 特点

  • 易于拓展:就是数据之间没有关系。
  • 大数据高性能:可以一次写入多条数据,性能更高。
  • 数据类型多样

NoSQL 数据库的四大分类

  • KV键值: Redis

  • 文档型数据库(bson格式比较多): MongoDB,基于分布式文件存储的数据库;

  • 列存储数据库: HBase,分布式文件系统;

  • 图关系数据库: 存放社交网络,推荐系统等,专注于构建关系图谱;

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gd5buzTd-1620977428944)(E:\md笔记\markdown_pic\clipboard-1620976389796.png)]

Redis是什么

什么是Redis,Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

Redis特点

  • Redis以内存作为数据存储介质,读写数据的效率极高。
  • Redis跟memcache不同的是,储存在Redis中的数据是持久化的,断电或重启,数据也不会丢失。
  • Redis的存储分为内存存储、磁盘存储和log文件。
  • Redis可以从磁盘重新将数据加载到内存中,也可以通过配置文件对其进行配置,因此,redis才能实现持久化。
  • Redis支持主从模式,可以配置集群,更利于支撑大型的项目。
Redis的安装

以上都是理论的东西,现在开始实践,安装呢,我选择在docker安装,毕竟这个比较香,不用整花里胡哨的。

走起,直接安装最新版
docker pull redis

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z4ru1jyy-1620977428947)(E:\md笔记\markdown_pic\clipboard-1620976564283.png)]

可以看到镜像已经安装好了,run直接运行,需要注意的是,Redis的默认端口号是6379,所以我们可以暴露这个端口。然后我的习惯是把配置文件挂载到默认的数据卷中。

docker run -idt --name hyx_redis -p 6379:6379 -v redis_conf:/etc/redis/redis.conf 74d107221092
目录在这里
/var/lib/docker/volumes/redis_conf/_data

然后我们看一下容器的日志,可以看到已经配置好了,等待连接。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-97FqvtVu-1620977428952)(E:\md笔记\markdown_pic\clipboard-1620976596437.png)]

然后我们进入容器,连接一下

 docker exec -it 4abb124b4e9e /bin/bash
 redis-cli 连接Redis
Redis基本命令
Redis默认有16个数据库,可以使用select 数字  来切换不同的数据库
可以使用DBSIZE来查看数据库的使用情况

在这里插入图片描述

keys *  //查看所有的key
flushall  //清除所有数据库的数据
flushdb  //清除当前数据库的数据
*************************************************************************
exists key_name  //查询变量是否存在,存在返回1,不存在返回0
move key_name 1  //移除当前数据库的这个变量
expire key_name 秒数  //变量存活时间,单位为秒
type key_name  //查看变量类型
字符串命令
append key_name 新内容  //类型拼接字符串,追加
strlen key_name  //查看字符串长度
incr key_name  //自增加1,可以达到计数的效果,就是i++
incrby key_name 数值   //按照数值步长自增
decr key_name //同理,这是减1
decrby key_name //按照数值步长自减
getrange key_name 开始位置 结束位置  //截取字符串
*************************************************************************
可以set时直接指定到期时间
setex key_name 到期时间 值
127.0.0.1:6379> setex price 10 10.2  # 十秒后过期
setnx key value  //if not exist 不存在时创建
mset k1 v1 k2 v2 ....  //一个设置多个key
对象操作
对象操作
set 对象名:对象编号{键值对} #来声明对象
set user:1 {name:heyexi,weight:50}
get user1  //获得对象
List操作
List操作

给列表添加元素
lpush 列表名 值.....
127.0.0.1:6379> lpush list heyeix nihao
(integer) 2
127.0.0.1:6379> lpush list world
(integer) 3
127.0.0.1:6379> lrange list 0 -1  //拿出所有数据
1) "world"
2) "nihao"
3) "heyeix"
lpush  是加在头部,rpush是加在尾部
*************************************************************************
移除列表元素,有lpop和rpop
127.0.0.1:6379> lrange list 0 -1
1) "world"
2) "nihao"
3) "heyeix"
127.0.0.1:6379> rpop list
"heyeix"
*************************************************************************
获取指定下标的值
lindex 列表名 下标
127.0.0.1:6379> lindex list 0
"world"
*************************************************************************
获取列表长度
llen 列表名
127.0.0.1:6379> llen list
(integer) 2
Set操作
set操作
list操作都是l开头,那么set操作就是s开头
添加集合元素
sadd 集合名称 值...
127.0.0.1:6379> sadd myset 10 23 56 455
(integer) 4
*************************************************************************
查看集合成员
smembers set名称
127.0.0.1:6379> smembers myset
1) "10"
2) "23"
3) "56"
4) "455"
*************************************************************************
判断某个元素是否是该集合成员 类型contain
sismember 集合名称 查找的值
127.0.0.1:6379> sismember myset 12
(integer) 0  //不存在
127.0.0.1:6379> sismember myset 23
(integer) 1 //存在
*************************************************************************
获取长度
scard 集合名称
127.0.0.1:6379> scard myset
(integer) 4
*************************************************************************
移除某个值
srem 集合名 值1 值2...
127.0.0.1:6379> srem myset 23
(integer) 1
127.0.0.1:6379> scard myset
(integer) 3
*************************************************************************
查询第一个集合不同于第二个集合独有的元素
sdiff 集合1 集合2
127.0.0.1:6379> smembers myset
1) "10"
2) "56"
3) "455"
127.0.0.1:6379> sadd set1 10 23 66
(integer) 3
127.0.0.1:6379> sdiff myset set1
1) "56"
2) "455"
可以看到获得了第一个元素自己不同于第二个集合的元素
*************************************************************************
获取交集
sinter 集合1 集合2
127.0.0.1:6379> sinter myset set1
1) "10"
*************************************************************************
获取并集
sunion 集合1 集合2
127.0.0.1:6379> sunion myset set1
1) "10"
2) "23"
3) "56"
4) "66"
5) "455"
hash操作
hash(哈希)操作
想到hash就是想到java的hashmap
就是和Redis的set和get一样,只是这时是变成了hashmap,很明显的套娃
*************************************************************************
使用哈希set和get就变成了hset和hget
127.0.0.1:6379> hset myhash k1 hello k2 world
(integer) 2
127.0.0.1:6379> hget myhash k1
"hello"
*************************************************************************
删除值
127.0.0.1:6379> hdel myhash k1
(integer) 1
*************************************************************************
获取长度
127.0.0.1:6379> hlen myhash
(integer) 1
*************************************************************************
判断指定key是否存在
127.0.0.1:6379> hexists myhash k1
(integer) 0
*************************************************************************
获取所有的key
127.0.0.1:6379> hkeys myhash
1) "k2"
2) "k4"
3) "k5"
4) "k6"
*************************************************************************
获取所有的value
127.0.0.1:6379> hvals myhash
1) "99"
2) "90"
3) "99"
4) "90"
*************************************************************************
哈希保存对象信息,保存实体数据,一般使用哈希
127.0.0.1:6379> hset style:1 name css color red top 20px
(integer) 3
127.0.0.1:6379> hget style:1 name 
"css"
Jedis

什么是jedis,jedis是java连接Redis的连接开发工具,相当于中间件,java通过操作jedis来操作Redis数据库。

新建一个Maven项目,然后倒入jedis依赖。

<dependencies>
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
</dependencies>

然后写代码测试连接,记得开阿里云6379端口

public static void main(String[] args)
{

    Jedis jedis = new Jedis("主机ip",6379);
    System.out.println(jedis.ping());//测试连接
}
输出:
PONG
说明连接成功

常用的api

上面的命令在jedis就是一个个的方法

public static void main(String[] args)
{
    Jedis jedis = new Jedis("ip",6379);
    System.out.println("查询所有keys"+jedis.keys("*"));
    System.out.println("查询key是否存在"+jedis.exists("heyexi"));
    System.out.println("set一个key"+jedis.set("name","何夜息"));
    System.out.println("获取key"+jedis.get("name"));
    jedis.close();//关闭连接
}
输出
查询所有keys[myhash, user:1, set1, style:1, list, test, myset]
查询key是否存在false
set一个key OK
获取key何夜息

其他都是一样的
Jedis的事务操作

事务就是一组连续的操作,应该遵循acid原则,但是Redis的事务,单条语句是遵循原子性的,但是事务就不是了,只要编译没有错误,也就是命令没错,中间的一条命令发生错误,其他没有发生错误的能够进行执行。

事务的格式很简单:

multi //代表事务开始
中间就是一系列的命令
exec  //事务结束
discard //代表放弃事务
@org.junit.Test
public void test1()
{
    Jedis jedis = new Jedis("ip",6379);
    //开启事务
    Transaction multi = jedis.multi();

    try{
        //开始事务的一系列操作
        multi.set("day","星期六");
        multi.set("color","blue");
        //执行事务
        multi.exec();

        System.out.println(jedis.get("day"));
        System.out.println(jedis.get("color"));
    }catch (Exception e)
    {
        //发错误放弃事务
        multi.discard();
    }finally
    {
        jedis.close();
    }
}

输出
星期六
blue
SpringBoot整合jedis

现在就到了运用部分了,可以整合到SpringBoot开发项目了。

首先就是添加依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
  <version>2.3.4.RELEASE</version>
</dependency>

然后在配置文件中配置Redis

#redis配置
spring.redis.host=服务器地址
spring.redis.port=6379

最后就是操作Redis了

因为整合到了SpringBoot,所以就不用使用jedis了,可以使用RedisTemplate,和JdbdTemplate是一样的。

redisTemplate.opsForXX()
xx就代表数据类型,就是Redis的数据类型,代表选择我们要操作的数据类型。

@Autowired
private RedisTemplate redisTemplate;

@Test
void redis()
{
    redisTemplate.opsForValue().set("bgImg","https://www.heyexi.com/xxx.jpg");
    System.out.println(redisTemplate.opsForValue().get("bgImg"));

}
输出
https://www.heyexi.com/xxx.jpg

然后我们打开服务器查看,发现前面加了一些内容,如何解决呢?

在这里插入图片描述

然后我们再来看一下存一个实体对象,这个实体务必要序列化,不然会出错。这是我某个项目的一个实体类,直接拿来用了。

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Component
public class Balance implements Serializable
{
    // 主键ID
    private Long id;
    // 用户类型
    private String ba_user_type;
    // 用户编号
    private Long ba_user_id;
    // 可提现金额
    private Float ba_balance;
    // 冻结金额
    private Float ba_frozen;
    // 更新时间
    private Timestamp ba_status_time;
    // 创建时间
    private Timestamp create_date;
    // 备注
    private String remark;
    // 数据状态
    private Byte status;
}

开始测试

@Autowired
private RedisTemplate redisTemplate;
@Autowired
private Balance balance;

@Test
void redis()
{
    balance.setBa_balance(20.53f);
    balance.setBa_status_time(DateUtil.getNowSqlDateTime());
    balance.setBa_user_id(Long.valueOf(18));
    balance.setStatus(Byte.valueOf("1"));
    
    redisTemplate.opsForValue().set("balance",balance);
    System.out.println(redisTemplate.opsForValue().get("balance"));

}
输出如下:
Balance(id=null, ba_user_type=null, ba_user_id=18, ba_balance=20.53, ba_frozen=null, ba_status_time=2020-12-17 16:44:43.903, create_date=null, remark=null, status=1)

在这里插入图片描述

还是出现这个问题,这个是因为Redis默认的序列化是jdk的序列化方式,我们需要自己重新定义RedisTemplate的序列化方式。

新建一个Redis的配置类。

@Configuration
public class MyRedis
{
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
    {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 设置其他的k-v的默认的序列化
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer(Object.class));
        //单独设置k的序列化
        template.setKeySerializer(new StringRedisSerializer());

        return template;
    }
}

然后再运行查看就发现OK了

在这里插入图片描述

最后就是我们每次操作Redis都需要获取template,而且方法不方便使用,所以项目开发中都会使用通用的工具类,以下就是一个通用的Redis操作工具了,可以直接在项目中使用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public final class RedisUtils
{
    private RedisUtils() {}

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    // =============================common============================
    /**
     * 指定缓存失效时间
     * @param key  键
     * @param time 时间(秒)
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }


    /**
     * 判断key是否存在
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 删除缓存
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }


    // ============================String=============================

    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */

    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 普通缓存放入并设置时间
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */

    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 递增
     * @param key   键
     * @param delta 要增加几(大于0)
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }


    /**
     * 递减
     * @param key   键
     * @param delta 要减少几(小于0)
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }


    // ================================Map=================================

    /**
     * HashGet
     * @param key  键 不能为null
     * @param item 项 不能为null
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     * @param key 键
     * @param map 对应多个键值
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * HashSet 并设置时间
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }


    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }


    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }


    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }


    // ============================set=============================

    /**
     * 根据key获取Set中的所有值
     * @param key 键
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0)
                expire(key, time);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 获取set缓存的长度
     *
     * @param key 键
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */

    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    // ===============================list=================================

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取list缓存的长度
     *
     * @param key 键
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 将list放入缓存
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }


    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }


    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */

    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */

    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }

    }
}
然后来使用这个工具类就变得很方便
@Autowired
private RedisUtils redisUtils;
@Autowired
private Balance balance;

@Test
void redis()
{
    balance.setBa_balance(20.53f);
    balance.setBa_status_time(DateUtil.getNowSqlDateTime());
    balance.setBa_user_id(Long.valueOf(18));
    balance.setStatus(Byte.valueOf("1"));

    redisUtils.set("new_balance",balance);
    System.out.println(redisUtils.get("new_balance"));
}

在这里插入图片描述

给Redis设置连接密码

Redis默认连接是没有密码的,我们可以通过命令行来设置连接密码

config set requirepass "密码"
Redis持久化

Redis是内存数据库,只要服务停止,那么数据就会丢失,所以我们有必要进行数据持久化。

Redis提供了两种持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)。

上网查询了这两种机制的介绍如下:

​ RDB其实就是把数据以快照的形式保存在磁盘上。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

在这里插入图片描述

可以看进入docker容器后,在data目录里就有这个文件,里面就是我设置的内容。

全量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。

在这里插入图片描述

总结:

rdb就是根据配置文件中sava的时间间隔数值,在固定的时间内去保存数据,做持久化,缺点就是如果意外停止,可能导致最后几条数据来不及持久化。

aof就是把每个命令都保存在aof文件总,追加写入命令,恢复时通过命令来恢复。

但是我们一般使用默认的rdb就行了,因为这样效率高,aof占用空间大,而且Redis只是作为一个缓存的数据库,重要的持久化数据都保存在其他数据库,所以效率和性能是最重要的,这是我的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值