Redis01-常规使用

一、redis介绍

Redis是一款由C语言编写的,开源的,内存型数据库,性能非常强悍。因为他存储方式和传统关系型数据库不一样,没有表的概念,也被称为NoSQL(not only SQL)。

Redis支持的数据类型有:

  • 字符串(strings):就是字符串,string
  • 散列(hashes) :可以理解为map,hash
  • 列表(lists):可以理解为list集合,链表结构,list
  • 集合(sets):可以理解为set集合,set
  • 有序集合(sorted sets):可以理解为有序的set集合,zset
  • 等等

官网:https://redis.io/
中文网:http://redis.cn/
历史版本地址:https://download.redis.io/releases/

二、redis安装

2.1 windows安装

windows版本下载地址1:https://github.com/microsoftarchive/redis/releases/
windows版本下载地址2(建议):https://github.com/tporadowski/redis/releases/
建议使用
建议下载绿色版,使用方便,解压即可使用。也可进群文件(1109193029)下载,这里咱们使用绿色版Redis-x64-5.0.14.1.zip
1.启动redis
将redis解压到非中文和特殊字符的路径下

Redis-x64-5.0.14.1
	|-- redis.windows.conf  #redis的配置文件
	|-- redis-cli.exe       #redis客户端
	|-- redis-server.exe    #redis服务端

在解压目录中找到redis-server.exe双击即可启动
在这里插入图片描述

2.使用客户端连接redis,双击 redis-cli.exe 即可启动客户端连接redis,使用ping命令测试,如果返回PONG,表示成功。
在这里插入图片描述
3.前面我们说到的启动redis服务端的方式是直接启动,如果我们进入配置文件redis.windows.conf将端口改动为port 6380,想让修改生效,则启动redis就必须读取到配置文件才行,打开 cmd,切换到redis的目录中,执行命令启动:

redis-server.exe redis.windows.conf

此时,直接双击redis-cli.exe已经无法连接到redis了,因为默认连接的是本机的6379端口,需要进入cmd命令行,切换到redis的目录,执行命令:

redis-cli.exe -p 6380      # -p端口

# 完整写法
redis-cli.exe -h 127.0.0.1 -p 6380    # -h ip -p 端口

2.2 Linux版安装

环境:CentOS7 + redis-6.2.7.tar.gz

1.安装gcc相关环境

yum install -y gcc

安装完毕,检查一下:gcc -v

2.Redis官网下载 tar包 ,或者进群文件(1109193029)下载,我这里用的是redis-6.2.7.tar.gz,并解压到 /usr/local/ 目录下。

3.进入redis的解压目录中,先执行:make,再执行 make install,执行结束表示安装完毕,此时,在 /usr/local/bin/ 中会生成对应的命令:redis-serverredis-cli 等命令,说明安装成功。

4.启动redis,进入redis的安装目录,执行命令

redis.server redis.conf

默认是前台启动,启动后该窗口就不能执行其他操作了,如果想连接redis必须重新启动一个窗口。
在这里插入图片描述
通过修改配置文件 redis.conf 可以变为后台运行。
在这里插入图片描述
启动后,查看redis是否启动成功

ps -ef | grep redis


说明redis-server已经在6379端口启动。

5.使用客户端连接redis服务端

redis-cli -p 6379

6.退出客户端

exit

7.停止服务

# 查看运行的redis-serer是否在运行
ps -ef | grep redis-server

# 停止服务器方式1(在客户端没有连接的状态下)
redis-cli shutdown
# 停止服务器方式2(在客户端连接的状态下)
shutdown

三、redis命令

命令大全地址:http://redisdoc.com/ 或者 http://redis.cn/commands.html

3.1 基础命令

# redis默认16个库,下标 0-15
dbsize       #查询当前数据库的key数据
flushdb      #清空当前数据库
flushall     #清空所有库
select [dbindex]          #切换数据库

keys *                    #查看当前库中的所有key
del [keyname]             #删除指定的key 
exists [keyname]          #判断指定key是否存在
move [keyname] [dbindex]  #将当前库的key移动到指定的库中
type [keyname]            #查看当前key的类型

ttl [keyname]    #查询key的剩余存活时间,-1 表示永不过期,-2表示已过期

3.2 string相关命令

#常用
set [keyname] [value]       #设置k-v,如果对相同key重复执行,后者会替换前者
get [keyname]               #获取key对应的值
del [keyname]               #删除key
append [keyname] [value]    #在原有值上追加内容
strlen [keyname]            #获取value的长度
expire [keyname] [seconds]  #为key设置过期时间,单位:秒
setex [keyname] [seconds] [value]    #设置k-v,同时设置过期时间
setnx [keyname] [value]     #设置k-v,只在key不存在时执行成功,如果key已经存在则失败

#数值才能使用
incr [keyname]               #对原值进行+1
decr [keyname]               #对原值进行-1
incrby [keyname] [number]    #对原值每次+number,每次增加指定步长
decrby [keyname] [number]    #对原值每次-number,每次减少指定步长

#获取区间范围的值
getrange [keyname] [start] [end]    
#例如:
127.0.0.1:6379>set k3 abcde
127.0.0.1:6379>getrange k3 0 3  
#结果:"abcd"    含头含尾

#替换指定区间范围的值
setrange [keyname] [start] [newValue]
#案例:
127.0.0.1:6379> get k1
"v12345"
127.0.0.1:6379> SETRANGE k1 0 "aa"
127.0.0.1:6379> get k1
"aa2345"

#批量操作 mset和mget,msetnx
mset key1 value key2 value key3 value
mget key1 key2 key3
msetnx key1 value key2 value key3 value
#msetnx是对当且仅当所有给定键都不存在时,为所有给定键设置值,有一个key存在操作整体失败

3.3 list相关命令

一key多值,有序,值可以重复

lpush [keyname] value1 value2 value3       #从表头添加元素
rpush [keyname] value1 value2 value3       #从表尾添加元素
lpop [keyname]               #从表头取出元素,取出后表中就没有该元素了
rpop [keyname]               #从表尾取出元素
#根据存取的方向不一样,可以实现队列或栈的结构

lindex [keyname] [index]     #查看指定下标的元素,从0开始
llen [keyname]               #查询表中的元素个数

lset [keyname] [index] [value]    #为表的指定下标index上设置值value
lrem [keyname] [count] [value]    #删除表中count个与value相等的元素,例如:lrem mylist 2 a ,意为:删除mylist中2个a
ltrim [keyname] [start] [stop]    #只保留下标从start开始到stop的元素,其余全部删除
rpoplpush [keyname1] [keyname2]   #取出表1的尾元素,插入到表2的表头

linsert [keyname] before/after value newValue #在表中指定的value前或后插入新值newValue

lrange [keyname] [start] [stop]  #查看列表key中指定区间内的元素,0 -1 表示查看全部

3.4 set相关命令

一key多值,无序,不允许重复

sadd [keyname] [value1] [value2]       #新建集合,并插入元素value1和value2
smembers [keyname]                     #查看集合key中的所有成员
scard [keyname]                        #查询集合的长度

spop [keyname]                         #随机弹出集合中的一个成员
smove [keyname1] [keyname2] [value]    #将元素value从集合1移动到集合2中
srem [keyname] [value]                 #删除集合中的指定元素value

sismember [keyname] [value]            #判断元素value在集合是否存在,包含返回1,不包含或者key不存在都返回0

sinter [key1] [key2 …]            #交集,返回第一个集合有,其他集合也有的元素
sdiff [key1] [key2 …]             #差集,返回第一个集合有,但是其他集合没有的元素
sunion [key1] [key2 …]            #并集,返回并集

3.5 hash相关命令

相当于map,value允许为空串

hset [mapname] [] []         #新增,不存在就新建,存在就替换旧值
hsetnx [mapname] [] []       #不存在才会新建,存在就放弃执行
hget [mapname] []              #获取指定的属性值,例如:hget student id
hgetall [mapname]                #获取所有属性和值
hdel [mapname] [键1 键2]          #删除哈希表中一个或者多个key
hlen [mapname]                   #查询哈希表中key的数量

hmget [mapname] [键1] [值1] [键2] [值2]     #批量设置,如果存在就替换原值
hmset [mapname] [键1] [键2]                 #批量获取

hexists [mapname] []           #判断指定的key是否存在

hkeys [mapname]              #获取所有key
hvals [mapname]              #获取所有value

hincrby [mapname] [] [number]        #对哈希表中的键所对应的值加上增量 number (可正数,可负数)
hincrbyfloat [mapname] [] [number]   #对哈希表中的键所对应的值加上增量 number (浮点数,可正数,可负数)

3.6 zset相关命令

有序的set集合,为集合中的元素增加了一个scores的概念(整数),相当于为数据加了一个序号,从而实现有序

# zadd 添加元素
语法: zadd 集合名 序号 元素

# zrem 删除指定集合中元素
语法:zrem 集合名 元素

# zrange 返回集合中的元素(升序)
语法:zrange 集合名 开始序号 结束序号 [withscores]      -- 可选:withscores 同时返回 序号

# zrevrange 返回集合中的元素(降序)
语法:zrange 集合名 开始序号 结束序号 [withscores]

# zincrby 对元素对应的序号进行增或减
语法: zincrby 集合名 number 元素         number 可正,可负
--如果元素存在就对序号+number操作,不存在就在number序号处插入元素

# zrank 返回元素对应的索引值( 不是序号 )
语法:zrank 集合名 元素     索引值从头开始,头第一个元素索引为0,向后递增

# zrevrank 返回元素对应的索引值,但是从尾开始,尾第一个元素索引为0,向前递增
语法: zrevrank 集合名 元素 

# zrangebyscore 先升序排序后,取范围内的元素
语法:zrangebyscore 集合名 开始序号 结束序号 [withscores]

# zcount 返回范围内的元素个数
语法:zcount 集合名 开始序号 结束序号

# zcard 返回集合全部的元素个数
语法:zcard 集合名

# zremrangebyrank 删除集合给定索引范围内的元素
语法:zremrangebyrank 集合名 开始索引 结束索引

# zremrangebyscore 删除集合给定序号范围内的元素
语法:zremrangebyscore 集合名 开始序号 结束序号

四、redis密码设置

4.1 设置密码

在配置文件(redis.conf)中添加密码:

######### SECURITY #########
requirepass 123456

4.2 启动服务

启动服务端时指定配置文件配置才会生效

redis-server.exe redis.conf

4.3 登录

启动 redis-cli 后,使用auth登录:

auth 123456

五、redis的图形界面化客户端

RedisDesktopManager 是用于连接redis的客户端,可以基于图形界面操作redis。
下载地址:https://en.freedownloadmanager.org/Windows-PC/Redis-Desktop-Manager-FREE.html
也可以在群文件(1109193029)中下载redis-desktop-manager-0.8.8.384.exe

六、redis持久化

Redis持久化支持两种方式:rdb和aof。

6.1 RDB模式

将当前数据库的内容执行快照保存到磁盘,恢复时读取文件将数据读入内存。
具体配置参考配置文件:redis.conf

################################ SNAPSHOTTING 快照(rdb)  ################################
save 900 1                               #900秒(15分钟)内如果超过1个key被修改,则发起快照保存
save 300 10								 #300秒(5分钟)内如果超过10个key被修改,则发起快照保存
save 60 10000                            #60秒(1分钟)内如果超过10000个key被修改,则发起快照保存,如果要禁用rdb,使用 save ""
stop-writes-on-bgsave-error yes          #如果在备份时出错了,要停止写操作,如果设置为no表示不在乎数据一致性
rdbcompression yes                       #启用LZF对备份进行压缩
rdbchecksum yes                          #在存储快照后,redis会启动CRC64算法进行校验,会增加10%的性能消耗
dbfilename dump.rdb                      #数据库快照备份时的文件名,rdb模式
dir ./                                   #快照文件存储位置,默认在当前目录

1.默认是开启的。根据设定的时间阈值进行数据库快照备份,快照文件默认存在 redis目录中的dump.rdb文件中。

2.恢复:redis启动就会自动读取dump.rdb将数据恢复

3.使用命令 savebgsave 可以立刻执行快照备份。区别是save指令的执行会阻塞当前redis服务,直到RDB过程完成为止,有可能会造成长时间的阻塞。bgsave指令的执行将会在后台进行,当我们执行该指令后,redis会调用fork函数生成一个子进程,然后在子进程中创建RDB文件。

4.使用命令flushall 也会生成备份文件,但是是空的,没有意义

6.2 AOF模式

将数据库每一步写操作命令记录到文件中。
具体配置参考配置文件:redis.conf

############################## APPEND ONLY MODE (备份:AOF模式) ###############################
appendonly no                       #aop的开关,默认关闭(no/yes),当rdb和aof都开启时,redis重启后是首先加载aof的备份文件
appendfilename "appendonly.aof"     #备份的文件名
appendfsync everysec                #持久化策略
									# always:同步操作,每次数据发生变化就立刻记录到磁盘,性能消耗大
									# everysec:每秒种执行备份,异步操作,但是有较小(1秒)的数据丢失风险(推荐)
									# no:redis不会主动进行同步操作,依赖于操作系统,整体过程不可控(不推荐)
									
no-appendfsync-on-rewrite no        #重写时是否使用appendfsync,默认为no
auto-aof-rewrite-percentage 100     #重写时的阈值 100%  1倍的意思
auto-aof-rewrite-min-size 64mb      #重写时的阈值
aof-load-truncated yes              #redis在恢复时,会忽略最后一条可能存在问题的指令

1.当rdb和aof同时开启时,redis启动时优先加载aof的配置文件,如果文件中有语法错误,可以使用redis自带命令redis-check-aof来修复。

redis-check-aof --fix appendonly.aof

2.AOF重写

  • 什么是重写?
    因为aof是记录命令,所以aof文件会越来越大,为了优化,增加了重写机制。
    当文件大小超过了设置的大小,就会对文件进行压缩,只保留可以恢复数据的最小命令集,可以使用命令:bgrewriteaof执行重写。
  • 触发机制?
    redis会记录上次重写时的文件大小,默认是:当aof文件大小是上次重写后的大小的一倍且文件大于64MB时触发。

重写配置详见 redis.conf 中的配置:

no-appendfsync-on-rewrite no        # 这几个配置前面有相关解释
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

七、SpringBoot整合Redis

早先我们使用Jedis来操作redis,他是一个相对原生的redis的客户端,但是随着springboot越来越火热,springboot还帮我们做了很多默认的集成工作,所以今天咱们使用springboot提供的RedisTemplate来操作redis。

7.1 导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.10</version>
    <relativePath/>
</parent>
...
<dependencies>
    <!--springbootweb依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--springboot整合redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--测试依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

7.2 配置参数

application.yml

spring:
  redis:
    host: 127.0.0.1 #ip地址
    port: 6379      #端口
    # database: 0   #默认连接0号数据库
    # password: 123456     #密码
    lettuce:  #连接池设置,springboot2.x以后底层使用lettuce连接redis,老版本的springboot底层用的jedis
      pool:
        max-active: 8 #最大连接数
        max-idle: 8   #最大空闲数
        min-idle: 0   #最小空闲数
        max-wait: 3000  #连接超时时间(毫秒)

这里需要注意的是,redis默认只允许本地连接,因为在配置文件redis.conf中的有bind配置:bind 127.0.0.1

7.3 RedisTemplate操作redis

极简入门

@SpringBootTest
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test //尝试存入值 和  获取值
    public void test(){
        redisTemplate.opsForValue().set("myname","tom");
        System.out.println(redisTemplate.opsForValue().get("myname")); //tom
    }
}

7.4 自定义RedisTemplate序列化方式

虽然前面的案例,存入和获取都是成功的,但是如果在命令行下查看,或者使用RedisDesktopManager 查看key和value发现是无法正常查看的。
在这里插入图片描述
这个不是错,是因为 RedisTemplate 默认使用的序列化器是 JdkSerializationRedisSerializer(JDK序列化,是默认的),源码中可以看到:
在这里插入图片描述
而JDK序列化器存储后的结果不方便人工排查,并且对于递增和递减等操作是不支持的。所以,我们需要重新定义RedisTemplate的序列化方式。那如何定义呢?从RedisAutoConfiguration中可以看出:

public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }
    @Bean
    //如果redisTemplate这个bean不存在,就使用该bena,如果存在就不会使用该bean
    //那我们就自己提供一个RedisTemplate的bean来覆盖他这个默认的bean即可
    @ConditionalOnMissingBean(name = {"redisTemplate"}) 
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
	...
}

自定义RedisTemplate序列化方式:

@Configuration
public class RedisTemplateConfig {
    //自定义的RedisTemplate
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 1.创建 redisTemplate
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 2.设置连接池工厂
        template.setConnectionFactory(redisConnectionFactory);
        // 3.设置key的序列化器为:StringRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer); //也可以使用:RedisSerializer.string()直接获取
        //template.setHashKeySerializer(stringRedisSerializer);

        // 4.设置value的序列化器(底层使用jackjson)
        GenericJackson2JsonRedisSerializer gjjrs = new GenericJackson2JsonRedisSerializer();
        template.setValueSerializer(gjjrs); //也可以使用RedisSerializer.json()直接获取
        
        template.afterPropertiesSet();
        return template;
    }
}

解释:
1.redis中存储内容时,key一般都是字符串类型,所以key的序列化选择使用StringRedisSerializer
2.value序列化使用GenericJackson2JsonRedisSerializer,他允许value直接存入对象,并将对象转为json存储,见案例:将Person对象存入redis。

public class Person {
    private Integer id;
    private String name;
	//构造,get,set...
}
@SpringBootTest
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void test1(){
        redisTemplate.opsForValue().set("preson",new Person(1,"tom"));
        System.out.println(redisTemplate.opsForValue().get("preson")); //Person{id=1, name='tom'}
        System.out.println(redisTemplate.opsForValue().get("preson").getClass()); //class cn.msk.domain.Person
    }
}

根据代码打印结果,可以看到存入和取出都是正常的。但是,如果我们去Redis种查看:

{
  "@class": "cn.msk.domain.Person",
  "id": 1,
  "name": "tom"
}

除了正常的对象数据以外会有一个@class属性,记录这个json对象的类型,反序列化时能够正确的转为Person类型对象返回。但是这无疑就增加了内存开销,同时效率稍低。

另一个方案是将对象转为json字符串存入redis,可以使用Jackson2JsonRedisSerializer作为序列化器,这样就不会有额外的开销。

@Configuration
public class RedisTemplateConfig {
    //自定义的RedisTemplate
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 1.创建 redisTemplate
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 2.设置连接池工厂
        template.setConnectionFactory(redisConnectionFactory);
        // 3.设置key的序列化器为:StringRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer); //也可以使用:RedisSerializer.string()直接获取
        //template.setHashKeySerializer(stringRedisSerializer);

        // 4.设置value的序列化器,使用:Jackson2JsonRedisSerializer 
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        
        template.afterPropertiesSet();
        return template;
    }
}

测试存入数据:

@SpringBootTest
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void test1() throws JsonProcessingException {
        //1.将person转为json字符串
        Person person = new Person(1, "tom");
        ObjectMapper om = new ObjectMapper();
        String json = om.writeValueAsString(person);
        //2.存入json字符串
        redisTemplate.opsForValue().set("preson",json);
        //3.获取json字符串
        String presonStr = (String)redisTemplate.opsForValue().get("preson");
        //4.将json转为对象
        Person p = om.readValue(presonStr, Person.class);
        System.out.println(p);
    }
}

如果不转为换json字符串,使用Jackson2JsonRedisSerializer直接将对象存入也是可以的,但是获取时就会出错,无法造型为Person对象,因为返回的是java.util.LinkedHashMap

八、RedisTemplate常用方法

8.1 操作key

//判断key是否存在
redisTemplate.hasKey(key);

//有则取出key值所对应的值;
redisTemplate.opsForValue().get(key);

//删除单个key值;
redisTemplate.delete(key);

//批量删除key;
redisTemplate.delete(keys); //其中keys:Collection<K> keys

//将当前传入的key值序列化为byte[]类型;
redisTemplate.dump(key);

//设置过期时间
//unit时间单位(TimeUnit.DAYS:天,TimeUnit.HOURS:时,TimeUnit.MINUTES:分,TimeUnit.SECONDS:秒,TimeUnit.MILLISECONDS:毫秒)
Boolean  redisTemplate.expire(key, timeout, unit); // 多久以后过期
Boolean  redisTemplate.expireAt(key, date);        // Date date 具体过期时间

//查找匹配的key值,返回一个Set集合类型( * 代表查询所有);
Set<String> redisTemplate.keys(pattern); // pattern为正则表达式

//修改redis中key的名称;
void redisTemplate.rename(oldKey, newKey);
 
//如果旧值存在时,将旧值改为新值
Boolean redisTemplate.renameIfAbsent(oldKey, newKey); 

//返回传入key所存储的值的类型;
DataType redisTemplate.type(key);

//从redis中随机取出一个key;
redisTemplate.randomKey();

//返回当前key所对应的剩余过期时间;
Long redisTemplate.getExpire(key);  
// TimeUnit unit 指定返回的时间的单位  
Long redisTemplate.getExpire(key, unit);

//将key持久化保存
Boolean redisTemplate.persist(key);

//将当前数据库的key移动到指定redis中数据库当中;
Boolean redisTemplate.move(key, dbIndex);

8.2 操作string

//设置当前的key以及value值;
redisTemplate.opsForValue().set(key, value);
 
// 带过期时间timeout,和时间单位unit
redisTemplate.opsForValue().set(key, value, timeout, unit);

//返回key中字符串 start~end 位置的子字符;
String redisTemplate.opsForValue().get(key, start, end);

//将旧的key设置为value,并且返回旧的key;
String redisTemplate.opsForValue().getAndSet(key, value);

//批量获取值;
List<String> redisTemplate.opsForValue().multiGet(keys); // Collection<String> keys

//在原有的值基础上新增字符串到末尾;
redisTemplate.opsForValue().append(key, value);

//给 key 对应的 value 值进行自增(正值则自增,负值则自减),如果该 key 没有 value值,则默认为 0;
Double redisTemplate.opsForValue().increment(key, increment); // double increment
Long redisTemplate.opsForValue().increment(key, increment);   // long increment

//如果对应的map集合名称不存在,则添加否则不做修改;
Map valueMap = new HashMap();  
valueMap.put("valueMap1","map1");  
valueMap.put("valueMap2","map2");  
valueMap.put("valueMap3","map3");  
redisTemplate.opsForValue().multiSetIfAbsent(valueMap); 

//设置map集合到redis;
Map valueMap = new HashMap();  
valueMap.put("valueMap1","map1");  
valueMap.put("valueMap2","map2");  
valueMap.put("valueMap3","map3");  
redisTemplate.opsForValue().multiSet(valueMap);  

//获取字符串的长度;
redisTemplate.opsForValue().size(key);

//用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始;
redisTemplate.opsForValue().set(key, value, offset);

//重新设置key对应的值,如果存在返回false,否则返回true;
redisTemplate.opsForValue().setIfAbsent(key, value);

//将值 value 关联到 key,并将 key 的过期时间设为 timeout;
redisTemplate.opsForValue().set(key, value, timeout, unit);

//对key所储存的字符串值,获取指定偏移量上的位(bit);
redisTemplate.opsForValue().getBit(key, offset);

//将二进制第offset位值变为value;
redisTemplate.opsForValue().setBit(key, offset, value);

8.3 操作list

//通过索引获取列表中的元素;
redisTemplate.opsForList().index(key, index);

//获取列表指定范围内的元素(start开始位置, 0是开始位置,end 结束位置, -1返回所有);
redisTemplate.opsForList().range(key, start, end);

//存储在list的头部,即添加一个就把它放在最前面的索引处;
redisTemplate.opsForList().leftPush(key, value);

//把多个值存入List中(value可以是多个值,也可以是一个Collection value);
redisTemplate.opsForList().leftPushAll(key, value);

//List存在的时候再加入;
redisTemplate.opsForList().leftPushIfPresent(key, value);

//如果pivot处值存在则在pivot前面添加;
redisTemplate.opsForList().leftPush(key, pivot, value);

//按照先进先出的顺序来添加(value可以是多个值,或者是Collection var2);
redisTemplate.opsForList().rightPush(key, value);
redisTemplate.opsForList().rightPushAll(key, value);

//在pivot元素的右边添加值;
redisTemplate.opsForList().rightPush(key, pivot, value);

//设置指定索引处元素的值;
redisTemplate.opsForList().set(key, index, value);

//移除并获取列表中第一个元素(如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止);
redisTemplate.opsForList().leftPop(key);
redisTemplate.opsForList().leftPop(key, timeout, unit);

//移除并获取列表最后一个元素;
redisTemplate.opsForList().rightPop(key); 
redisTemplate.opsForList().rightPop(key, timeout, unit);

//从一个队列的右边弹出一个元素并将这个元素放入另一个指定队列的最左边;
redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey);
redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit);

//删除集合中值等于value的元素(index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素);
redisTemplate.opsForList().remove(key, index, value);

//将List列表进行剪裁;
redisTemplate.opsForList().trim(key, start, end);

//获取当前key的List列表长度;
redisTemplate.opsForList().size(key);

8.4 操作set

//1. 添加元素
redisTemplate.opsForSet().add(key, values);
//2.移除元素(单个值、多个值)
redisTemplate.opsForSet().remove(key, values);
//3. 删除并且返回一个随机的元素
redisTemplate.opsForSet().pop(key);
//4.获取集合的大小
redisTemplate.opsForSet().size(key);
//5.判断集合是否包含value
redisTemplate.opsForSet().isMember(key, value);
//6.获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
redisTemplate.opsForSet().intersect(key, otherKey)
//7.获取多个集合的交集(Collection var2)
redisTemplate.opsForSet().intersect(key, otherKeys);
//8.key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)
redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey);
//9.key集合与多个集合的交集存储到destKey无序集合中;
redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey);
//10.获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合);
redisTemplate.opsForSet().union(key, otherKeys);
//11.key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合);
redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
//12.获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合);
redisTemplate.opsForSet().difference(key, otherKeys);
//13.差集存储到destKey中(otherKeys可以为单个值或者集合);
redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey);

//14.随机获取集合中的一个 或 count个元素;
redisTemplate.opsForSet().randomMember(key);
// 随机获取集合中count个元素
redisTemplate.opsForSet().randomMembers(key, count);

//15.获取集合中的所有元素
redisTemplate.opsForSet().members(key);
//16.获取多个key无序集合中的元素(去重),count表示个数
redisTemplate.opsForSet().distinctRandomMembers(key, count);
//17.遍历set类似于Interator(ScanOptions.NONE为显示所有的)
redisTemplate.opsForSet().scan(key, options);

8.5 操作zset

//添加元素(有序集合是按照元素的score值由小到大进行排列);
redisTemplate.opsForZSet().add(key, value, score);

//删除对应的value,value可以为多个值;
redisTemplate.opsForZSet().remove(key, values);

//增加元素的score值,并返回增加后的值;
redisTemplate.opsForZSet().incrementScore(key, value, delta);

//返回元素在集合的排名,有序集合是按照元素的score值由小到大排列;
redisTemplate.opsForZSet().rank(key, value);

//返回元素在集合的排名,按元素的score值由大到小排列;
redisTemplate.opsForZSet().reverseRank(key, value);

//获取集合中给定区间的元素(start 开始位置,end 结束位置, -1查询所有);
redisTemplate.opsForZSet().reverseRangeWithScores(key, start,end);

//按照分数范围升序输出名称;
redisTemplate.opsForZSet().rangeByScore(key, min, max);

//按照分数范围降序输出名称
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
//返回值为:Set<ZSetOperations.TypedTuple<V>>
redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);

//从高到低的排序集中获取分数在最小和最大值之间的元素;
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end);

//根据score值获取集合元素数量;
redisTemplate.opsForZSet().count(key, min, max);

//获取集合的大小;
redisTemplate.opsForZSet().size(key);
redisTemplate.opsForZSet().zCard(key);

//获取集合中key、value元素对应的score值;
redisTemplate.opsForZSet().score(key, value);

//移除指定索引位置处的成员;
redisTemplate.opsForZSet().removeRange(key, start, end);

//移除指定score范围的集合成员;
redisTemplate.opsForZSet().removeRangeByScore(key, min, max);

//获取key和otherKey的并集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合);
redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);

//获取key和otherKey的交集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合);
redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey);

//遍历集合(和iterator一模一样)
Cursor<TypedTuple<Object>> scan = opsForZSet.scan("test3", ScanOptions.NONE);
while (scan.hasNext()){
     ZSetOperations.TypedTuple<Object> item = scan.next();
     System.out.println(item.getValue() + ":" + item.getScore());
 }

8.6 操作hash

//以map集合的形式添加键值对;
redisTemplate.opsForHash().putAll(key, maps); // Map<String, String> maps

//获取变量中的键值对;
Map<Object, Object> redisTemplate.opsForHash().entries(key);

//查看hash表中指定字段是否存在;
Boolean redisTemplate.opsForHash().hasKey(key, field);

//获取变量中的指定map键是否有值,如果存在该map键则获取值,没有则返回null;
redisTemplate.opsForHash().get(key, field);

//新增hashMap值;
redisTemplate.opsForHash().put(key, hashKey, value);

//仅当hashKey不存在时才设置;
Boolean redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);

//删除一个或者多个hash表字段;
Long redisTemplate.opsForHash().delete(key, fields); // Object... fields

//给哈希表key中的指定字段的整数值加上增量increment;
public Double hIncrByDouble(String key, Object field, double delta) {
    return redisTemplate.opsForHash().increment(key, field, delta);
}
public Long hashIncrBy(String key, Object field, long increment) {
    return redisTemplate.opsForHash().increment(key, field, increment);
}

//获取所有hash表中字段;
redisTemplate.opsForHash().keys(key);

//获取hash表中字段的数量;
redisTemplate.opsForHash().size(key);

//获取hash表中存在的多个值;
List<Object> redisTemplate.opsForHash().values(key);

//匹配获取键值对,ScanOptions.NONE为获取全部键对;
public Cursor<Entry<Object, Object>> hashScan(String key, ScanOptions options) {
    return redisTemplate.opsForHash().scan(key, options);
}

8.7 基于RedisTemplate封装工具类

@Component
public final class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 指定缓存失效时间
     * @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((Collection<String>) 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;
        }

    }
}
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值