SpringBoot(七) - Redis 缓存
1、五大基本数据类型和操作
1.1 字符串-string
命令 | 说明 |
---|---|
set key value | 如果key还没有,那就可以添加,如果key已经存在了,那会覆盖原有key的值 |
get key | 如果key还没有,获取为(nil),代表key没有被使用,如果key存在,可以获取对应key的值 |
exists key | 判断某个key是否存在,返回Integer值1 代表存在,如果 exists car2 则返回0,不存在 |
move key db | 将当前数据库存在的键值移动到其它数据库,其中db是数据库的序号 |
expire key 秒钟 | 为已经存在的key设置过期时间,注意过期之后,从内存中去掉了,是get不到的 |
ttl key | 查看还有多少秒过期,-1表示永不过期,-2表示已过期 |
type key | 命令用于返回 key 所储存的值的类型 |
del key | 根据key值删除 |
append key value | 根据key将其值进行字符串拼接 |
strlen key | 根据key获取其值的字符串长度,字节数 |
incr key | 对key对应数值进行加一操作,对应的字符串值必须是数值 |
decr key | 对key对应数值进行减一操作 |
incrby key 数值 | 对key对应数值按照指定的值进行递增 |
decrby key 数值 | 对key对应数值按照指定的值进行递减 |
getrange key 起始位置 结束位置 | 获取指定区间内的值,类似between。。。and的关系,起始位置为0,结束位置为-1 就是返回所有 |
setrange key 起始位置 具体值 | 设置指定区间内的值,具体值会从起始位置开始覆盖 |
setex key 过期秒值 真实值 | 设置带过期时间的key,动态设置。 |
setnx key value | 只有在 key 不存在时,才会设置 key 的值,如果已经存在了,不覆盖,设置不了; |
setnx key value | 如果返回0 代表没有设置成功,key对应值已经存在,如果返回1代表设置成功;这个就是redis的分布式锁命令,很重要; |
mset key1 val1 key2 val2 .... | 同时设置一个或多个 key-value 对 |
mget key1 key2 key3 .... | 获取所有(一个或多个)给定 key 的值。 |
msetnx key1 val1 key2 val2 ..... | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在 |
1.2 列表-list
list操作起来类似于栈;
命令 | 说明 |
---|---|
lpush key val1 val2 val3 .... | 从左侧开始存放元素,先进后出 |
lrange key 起始位置 结束位置 | 从左侧开始,指定范围获取元素,-1代表所有 |
rpush key val1 val2 val3 .... | 从右侧开始存放元素,先进先出 |
lpop key | 从左侧一次取出一个元素 |
rpop key | 从右侧一次取出一个元素 |
lindex key index | 按照索引下标获得元素(从左到右,左下标从0开始,如果是-1代表最后一个,-2代表倒数第二个) |
llen key | 获取集合元素个数 |
lrem key 个数 具体的值 | 从左往右删除指定个数等于具体值的元素,返回的值为实际删除的数量,个数0,表示删除全部给定的值 |
ltrim key 开始index 结束index | 截取指定范围的值后再赋值给key |
rpoplpush 源列表 目的列表 | 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
lset key index value | 将key集合中的指定下标位置值改为value |
linsert key before/after 值1 值2 | 在list某个已有 值1 的前后再添加具体 值2 |
小结:
- 它是一个字符串链表,left、right都可以插入添加;
- 如果键不存在,创建新的链表;
- 如果键已存在,新增内容;
- 如果值全移除,对应的键也就消失了;
- 链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了;
1.3 集合-set
命令 | 说明 |
---|---|
sadd key val1 val2 ... | 集合set中添加元素,如果有重复元素会自动去除 |
smembers key | 查看集合中的元素 |
sismember key val | 判断val是否在set集合中,如果在返回1 ,不在返回0 |
scard key | 获取集合里面的元素个数 |
srem key value | 删除集合中元素 |
srandmember key 某个整数 | 随机出几个数,如果超过最大数量就全部取出 |
srandmember key 某个整数 | 如果写的值是负数,比如-3 ,表示需要取出3个,但是可能会有重复值。 |
spop key | 随机出栈 |
smove key1 key2 | 将key1里的某个值赋给key2 |
sdiff key1 key2 | 在第一个set里面而不在后面任何一个set里面的项 |
sinter key1 key2 | 在两个set中都有的值的交集返回 |
sunion key1 key2 | 在两个set中所有的值的集合返回,会自动排除重复 |
1.4 键值对-hash
K V模式不变,但V是一个键值对;
命令 | 说明 |
---|---|
hset 父key 子key 子value | 将父key,增加子键值对,类似属性 |
hget 父key 子key | 获取父key,某个子key的值,获取属性值 |
hmset 父key 子key1 子val1 子key2 子val2 .... | 批量添加属性 |
hmget 父key 子key1 子key... | 批量获取属性 |
hgetall 父key | 批量获取属性及值 |
hdel 父key 子key | 删除子key属性及值 |
hlen 父key | 返回父key中的子key个数,相当于java实体的属性个数 |
hexists 父key 子key | 判断父key中是否包含某个子key,结果为1,代表存在 |
hkeys 父key | 获取父key中所有的子key |
hvals 父key | 获取父key中的所有的子val |
hincrby 父key 子key 值 | 给指定的子key值增加固定的值 |
hincrbyfloat 父key 子key 值 | 给有指定key的值增加小数 |
hsetnx 父key 子key 子val | 如果子key存在则失败,如果不存在则赋值 |
1.5 有序集合-zset
在set基础上,加一个score值。之前set是k1 v1 v2 v3,现在zset是k1 score1 v1 score2 v2;
命令 | 说明 |
---|---|
zadd key score1 val1 score2 val2 score3 val3 ... | 有序集合添加带score值的元素 |
zscore key val | 获取集合中某个值对应score值 |
zrange key 0 -1 [withscores] | zrange zset1 0 -1 ,结果为所有的值,不带分数;如:zrange zset1 0 -1 ,结果为所有的值,不带分数 |
zrange zset1 0 -1 withscores | 结果为所有的值和分数 |
zrangebyscore key 开始score 结束score | 获取score值在开始score-结束score之间的元素 |
zrangebyscore zset1 10 40 | 获取score值在10-40之间的元素,包含10和40 |
zrangebyscore zset1 10 (40 | 不包含40值;( 的含义是不包含 |
zrangebyscore zset1 (10 (40 | 不包含10,40值 |
zrangebyscore zset1 10 50 limit 2 2 | limit 结果的起始下标,获取的个数;limit 含义是限制获取的条数,相当于mysql的分页; |
zrem key 某score下对应的value值 | 删除元素 |
zcard key | 获取key对应的值的个数;注意score 和 value是一个整体 |
zcount key score区间 | 获取分值区间内元素个数 |
zrank key values值 | 获得下标值 |
zscore key 对应value值 | 获得value对应分数 |
zrevrank key value值 | 逆序获得对应逆序的下标值 |
zrevrange key 起始下标,结束下标 | 将之前顺序进行倒序 |
zrevrangebyscore key 结束score 开始score | 根据score值输出元素 |
zincrby key 增加分值 value值 | 给对应的值增加score值 |
2、Redis整合
2.1 spring-boot-starter-data-redis 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2 redis配置
#端口号
server:
port: 8096
# redis配置
spring:
redis:
host: 127.0.0.1 #如果是redis远程服务器,此处redis服务器ip地址
port: 6379 #默认端口
# database: 0 #指定redis数据库,默认是0
# password: # 密码有就写,没有就省略
2.3 SpringBoot框架自动配置的redisTemplate
2.3.1 清空数据库
//自动装配 SpringBoot框架自动配置的redisTemplate
@Autowired
private RedisTemplate<Object,Object> redisTemplate;
//基于SpringBoot框架自动配置的redisTemplate,操作redis缓存
//获取连接
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//清空数据库中的所有数据
log.info("清空数据库中的所有数据");
connection.flushDb();
2.3.2 添加数据
//程序中,添加数据据到redis
log.info("------ 基于SpringBoot框架自动配置的redisTemplate 添加数据 ------");
redisTemplate.opsForValue().set("kh96_class_name","KGC_KH96");
redisTemplate.opsForValue().set("student_num",19);
2.3.3 获取数据
//程序中,从redis获取数据
log.info("------ 基于SpringBoot框架自动配置的redisTemplate 获取数据 ------");
log.info("****** 根据 班级的key:{},获取班级名称:{} ******","kh96_class_name",redisTemplate.opsForValue().get("kh96_class_name"));
log.info("****** 根据 班级的key:{},获取班级人数:{} ******","student_num",redisTemplate.opsForValue().get("student_num"));
2.3.4 修改值 (出现错误)
//程序中,基于SpringBoot框架自动配置的redisTemplate,操作redis缓存,存在问题
//场景:对班级人数进行增减操作,比如将班级人数,增加10
log.info("------ 基于SpringBoot框架自动配置的redisTemplate 操作数据 ------");
redisTemplate.opsForValue().increment("student_num",10);
//直接报错,会报500异常: redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
//原因,通过系统默认的 redisTemplate,存放key和value值时,会自动使用Object类的序列化和反序列化,导致redis中真实存放的数据不是原始值,而是序列化后的值
数据结果:
2.4 自定义redisTemplate
2.4.1 fastjson 依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
2.4.2 自定义redisTemplate 配置类
//Redis自定义配置类,实现一个自定义序列化方式的 redisTemplate,提缓缓掉默认自动配置的 redisTemplate,实现String类型任意类型的value
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 自定义redisTemplate的模板对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(redisConnectionFactory);
//由于要通过程序操作远程的redis数据库,必须支持序列化,才可以让程序中的数据,在网络中传输
//定义String类型的序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 定义fastjson序列化方式,可以序列化任何对象
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
// 需改为新的序列化方式
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// 初始化为新的模板
template.afterPropertiesSet();
return template;
}
}
2.4.3 使用自定义redisTemplate 重新操作数据
//自动装配自定义 redisTemplate
@Autowired
private RedisTemplate<String,Object> redisTemplate;
//其他代码不变
操作结果:
2.5 自定义redisUtils工具类
2.5.1 自定义redisUtils工具类
--->RedisUtil 工具类
2.5.2 使用自定义redisTemplate和redisUtils工具类
@GetMapping("/testRedisUtils")
public String testSpringBootRedisUtils(){
//基于自定义的redisTemplate 和 RedisUtils 工具类,操作redis缓存
//程序中,添加数据据到redis
log.info("------ 基于自定义的redisTemplate 和 RedisUtils 工具类 添加数据 ------");
redisUtils.set("kh96_class_name_utils","KGC_KH96");
redisUtils.set("student_num_utils",19);
//程序中,从redis获取数据
log.info("------ 基于自定义的redisTemplate 和 RedisUtils 工具类 获取数据 ------");
log.info("****** 根据 班级的key:{},获取班级名称:{} ******","kh96_class_name_utils",redisUtils.get("kh96_class_name_utils"));
log.info("****** 根据 班级的key:{},获取班级人数:{} ******","student_num_utils",redisUtils.get("student_num_utils"));
//程序中,基于SpringBoot框架自动配置的redisTemplate,操作redis缓存
//场景:对班级人数进行增减操作,比如姜班级人数,增加10
log.info("------ 基于自定义的redisTemplate 和 RedisUtils 工具类 操作数据 ------");
redisUtils.incr("student_num_utils",10);
return "工具类 RedisUtils 操作 redis 成功!";
}
2.5.3 程序中如何存放对象到 redis
核心思想:一般都是姜对象转换为json字符串,存入redis,获取对象数据,就先获取json字符串,再转换为对应对象即可;
@GetMapping("/testRedisUtils")
public String testSpringBootRedisUtils(){
//程序中如何存放对象到 redis
//核心思想:一般都是姜对象转换为json字符串,存入redis,获取对象数据,就先获取json字符串,再转换为对应对象即可
//模拟用户登录成功后,将用户信息存入redis中,方便后续从redis中获取用户信息
User loginUser = User.builder().userId(1001).userName("KH96").userTel("135012030404").build();
//直接将对象存入redis即可
log.info("------ 基于自定义的redisTemplate 和 RedisUtils 工具类 存储对象 ------");
//自动把实体,通过fastjson的序列化方式,转发为JSON字符串存储
redisUtils.set(loginUser.getUserId().toString(),loginUser);
//模拟获取登录用户信息,直接从redis获取存入的JSON字符串,转换为目标用户对象
User realUser = JSON.parseObject(redisUtils.get(loginUser.getUserId().toString()).toString(),User.class);
log.info("------ 基于自定义的redisTemplate 和 RedisUtils 工具类获取对象:{} ",realUser);
return "工具类 RedisUtils 操作 redis 成功!";
}
数据结果:
SpringBoot(七) - Redis 缓存的更多相关文章
- springboot整合redis缓存
使用springBoot添加redis缓存需要在POM文件里引入 org.springframework.bootspring-boot-starter-cacheorg.springframewor ...
- SpringBoot 整合 Redis缓存
在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ...
- SpringBoot使用redis缓存List<Object>
一.概述 最近在做性能优化,之前有一个业务是这样实现的: 1.温度报警后第三方通讯管理机直接把报警信息保存到数据库 2.我们在数据库中添加触发器,(BEFORE INSERT)根据这条报警信息处理业务 ...
- springboot集成redis缓存
1.pom.xml增加redis缓存起步依赖(spring-boot-starter-parent包含许多starter版本) <dependency> <groupId>or ...
- SpringBoot整合redis缓存(一)
准备工作 1.Linux系统 2.安装redis(也可以安装docker,然后再docker中装redis,本文章就直接用Linux安装redis做演示) redis下载地址: 修改redis,开启远 ...
- Java SpringBoot使用Redis缓存和Ehcache
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...
- springboot整合redis缓存一些知识点
前言 最近在做智能家居平台,考虑到家居的控制需要快速的响应于是打算使用redis缓存.一方面减少数据库压力另一方面又能提高响应速度.项目中使用的技术栈基本上都是大家熟悉的springboot全家桶,在 ...
- springboot 用redis缓存整合spring cache注解,使用Json序列化和反序列化。
springboot下用cache注解整合redis并使用json序列化反序列化. cache注解整合redis 最近发现spring的注解用起来真的是很方便.随即产生了能不能吧spring注解使用r ...
- SpringBoot使用redis缓存List
一.概述 最近在做性能优化,之前有一个业务是这样实现的: 1.温度报警后第三方通讯管理机直接把报警信息保存到数据库: 2.我们在数据库中添加触发器,(BEFORE INSERT)根据这条报警信息处理业 ...
随机推荐
- Docker-Compose和Docker Network的应用
1 # Docker-Compose分为两部分 2 # 一.Docker-Compose.yml 3 # 二.Docker-Compose 命令 4 5 # 桌面板的Docker(Win.Mac)会默 ...
- [算法1-排序](.NET源码学习)& LINQ & Lambda
[算法1-排序](.NET源码学习)& LINQ & Lambda 说起排序算法,在日常实际开发中我们基本不在意这些事情,有API不用不是没事找事嘛.但必要的基础还是需要了解掌握. 排 ...
- 笃情开源:我和 Apache DolphinScheduler 社区的故事
背景 本文的主人翁是 2 次飞机参会现场交流,四天研究就把 DolphinScheduler 用上生产的来自车联网行业的大数据 boy - 黄立同学.怎么样,听起来是不是有点 crazy?下面就来看看 ...
- .Net Core使用Coravel实现任务调度
前言 前段时间需要在一个新项目里添加两个后台任务,去定时请求两个供应商的API来同步数据:由于项目本身只是一个很小的服务,不太希望引入太重的框架,同时也没持久化要求:于是我开始寻找在Quartz.Ne ...
- OID天下第一 (双指针,LCT,线段树)
题面 或曰:"笑长天下第一!",OID 喜得合不拢嘴:"哈哈哈哈哈哈--" OneInDark 是天下第一的. OneInDark 给了你一个 n n n 个点 ...
- 【IDEA】IDEA打开欢迎页面
概述 IDEA在默认情况下,会进入最后一个项目.如果项目比较大的话会加载的比较久,这个就比较烦人了,目前我觉得最好的办法就是在设置中直接进入欢迎页面. 解决方案 ① 进入设置 ② Appearance ...
- 03 最小CMake项目
03 最小CMake项目 所有CMake项目都从一个CMakeLists.txt文件开始,此文件应该放在源代码树的最顶层目录下.可以将CMakeLists.txt想象成CMake项目文件,定义了从源和 ...
- 用trie树解决最大异或对问题(On)
在给定的N个整数A1,A2--ANA1,A2--AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...
- Python实验报告——第3章 流程控制语句
实验报告 [实验目的] 1.掌握python中流程控制语句的使用,并能够应用到实际开发中. [实验条件] 1.PC机或者远程编程环境 [实验内容] 1.完成第三章流程控制语句实例01-09,实战一到实 ...
- 13. 第十二篇 二进制安装kubelet
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483842&idx=1&sn=1ef1cb06 ...