Redis(redis基础,SpringCache,SpringDataRedis)

文章目录

  • 前言
  • 一、Redis基础
    • 1. Redis简介
    • 2. Redis下载与安装
    • 3. Redis服务启动与停止
    • 3 Redis数据类型
    • 4. Redis常用命令
    • 5. 扩展数据类型
  • 二、在Java中操作Redis
    • 1. Spring Data Redis的使用
      • 1.1. 介绍
      • 1.2. 环境搭建
      • 1.3. 编写配置类,创建RedisTemplate对象
      • 1.4. 通过RedisTemplate对象操作Redis
      • 1.5. 操作示例
    • 2. Spring Cache的使用
      • 2.1. 介绍
      • 2.2. 使用
      • 2.3. 注解详解
    • 3. Spring Data Redis常用API


前言

Redis从入门到精通,本文详细讲解了redis基础内容,以及Spring Cache,Spring Data Redis技术的使用


提示:以下是本篇文章正文内容,下面案例可供参考

一、Redis基础

1. Redis简介

Redis是一个基于内存的key-value结构数据库。非关系型数据库。
Redis 是互联网技术领域使用最为广泛的存储中间件。
官网:https://redis.io中文网:https://www.redis.net.cn/
key-value结构存储:
在这里插入图片描述

- 主要特点:- 基于内存存储,读写性能高 - 适合存储热点数据(热点商品、资讯、新闻)- 企业应用广泛Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。

NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。
关系型数据库(RDBMS):

	- Mysql- Oracle- DB2- SQLServer非关系型数据库(NoSql):- Redis- Mongo db- MemCached

2. Redis下载与安装

  • Redis下载
    Redis安装包分为windows版和Linux版:
    • Windows版下载地址:https://github.com/microsoftarchive/redis/releases
    • Linux版下载地址: https://download.redis.io/releases/
  • Redis安装
    • 在Windows中安装Redis(项目中使用)
      Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

    • 在Linux中安装Redis(简单了解)

      1. 将Redis安装包上传到Linux
      2. 解压安装包,命令:tar -zxvf redis-4.0.0.tar.gz -C /usr/local
      3. 安装Redis的依赖环境gcc,命令:yum install gcc-c++
      4. 进入/usr/local/redis-4.0.0,进行编译,命令:make
      5. 进入redis的src目录进行安装,命令:make install
    • 安装后重点文件说明:

      • /usr/local/redis-4.0.0/src/redis-server:Redis服务启动脚本
      • /usr/local/redis-4.0.0/src/redis-cli:Redis客户端脚本
      • /usr/local/redis-4.0.0/redis.conf:Redis配置文件
  • windows中安装成服务
    在这里插入图片描述
    在这里插入图片描述

    在系统服务中自动启动了
    在这里插入图片描述

3. Redis服务启动与停止

以window版Redis进行演示:

  1. 服务启动命令
    redis-server.exe redis.windows.conf
    在这里插入图片描述
    Redis服务默认端口号为 6379 ,通过快捷键Ctrl + C 即可停止Redis服务
    当Redis服务启动成功后,可通过客户端进行连接。
  2. 客户端连接命令
    redis-cli.exe
    在这里插入图片描述
    通过redis-cli.exe命令默认连接的是本地的redis服务,并且使用默认6379端口。也可以通过指定如下参数连接:
    • -h ip地址
    • -p 端口号
    • -a 密码(如果需要)
      注意:
    • 修改密码后需要重启Redis服务才能生效
    • Redis配置文件中 # 表示注释
      重启Redis后,再次连接Redis时,需加上密码,否则连接失败。
      在这里插入图片描述
      此时,-h 和 -p 参数可省略不写。
  3. Redis客户端图形工具
    默认提供的客户端连接工具界面不太友好,同时操作也较为麻烦,接下来,引入一个Redis客户端图形工具。直接安装即可。安装完毕后,直接双击启动
  • 新建连接
    在这里插入图片描述
  • 连接成功
    在这里插入图片描述

3 Redis数据类型

  1. 五种常用数据类型介绍
    Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型,key和value支持的最大是512M:
    • 字符串 string - 最常用 key:string
    • 哈希 hash key:map
    • 列表 list key: 列表 [1,2,3]
    • 集合 set key:set 无序
    • 有序集合 sorted set / zset key :zset
  • 各种数据类型特在这里插入图片描述
  • 解释说明:
    • 字符串(string):普通字符串,Redis中最简单的数据类型
    • 哈希(hash):也叫散列,类似于Java中的HashMap结构
    • 列表(list):按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList
    • 集合(set):无序集合,没有重复元素,类似于Java中的HashSet
    • 有序集合(sorted set/zset):集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素

4. Redis常用命令

  1. 字符串操作命令
    Redis 中字符串类型常用命令:

    • SET key value 设置指定key的值
    • GET key 获取指定key的值
    • SETEX key seconds value 设置指定key的值,并将 key 的过期时间设为 seconds 秒
    • SETNX key value 只有在 key 不存在时设置 key 的值
    • 更多命令可以参考Redis中文网:https://www.redis.net.cn
      在这里插入图片描述
  2. 哈希操作命令
    Redis hash 是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象,存储一些具有对应关系的数据,比如用户信息。
    常用命令:

    • HSET key field value 将哈希表 key 中的字段 field 的值设为 value
    • HGET key field 获取存储在哈希表中指定字段的值
    • HDEL key field 删除存储在哈希表中的指定字段
    • HKEYS key 获取哈希表中所有字段
    • HVALS key 获取哈希表中所有值
      在这里插入图片描述
  3. 列表操作命令
    Redis 列表是简单的字符串列表,按照插入顺序排序,可以用于实现消息队列、任务列表等场景。
    常用命令:

    • LPUSH key value1 [value2] 将一个或多个值插入到列表头部 left push
    • LRANGE key start stop 获取列表指定范围内的元素
    • RPOP key 移除并获取列表最后一个元素 remove pop
    • LLEN key 获取列表长度
    • BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超 时或发现可弹出元素
      在这里插入图片描述
  4. 集合操作命令
    Redis set 是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
    常用命令:

    • SADD key member1 [member2] 向集合添加一个或多个成员
    • SMEMBERS key 返回集合中的所有成员
    • SCARD key 获取集合的成员数
    • SINTER key1 [key2] 返回给定所有集合的交集
    • SUNION key1 [key2] 返回所有给定集合的并集
    • SREM key member1 [member2] 移除集合中一个或多个成员
      在这里插入图片描述
  5. 有序集合操作命令
    Redis有序集合是string类型元素的集合,且不允许有重复成员。每个元素都会关联一个double类型的分数。
    常用命令:

    • ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员zset add
    • ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员
    • ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
    • ZREM key member [member …] 移除有序集合中的一个或多个成员
      在这里插入图片描述
  6. 通用命令
    Redis的通用命令是不分数据类型的,都可以使用的命令:

    • KEYS pattern 查找所有符合给定模式( pattern)的 key EXISTS key 检查给定 key 是否存。
    • 在 TYPE key 返回 key 所储存的值的类型 DEL key 该命令用于在 key 存在是删除 key

5. 扩展数据类型

  1. geospatial 地理位置
  • Redis 在 3.2 推出 Geo 类型,该功能可以推算出地理位置信息,两地之间的距离 。
    有效的经度从 -180 度到 180 度。有效的纬度从 -85.05112878 度到 85.05112878 度。当坐标位置超出指定范围时,该命令将会返回一个错误。(error) ERR invalid longitude latitude pair xxx yyy
    常用的有如下命令
    • GEOADD key longitude latitude member [longitude latitude member …] 添加成员以及设置经纬度信息
    • GEODIST key member1 member2 [M | KM ] 返回2者之间的距离,M 和KM是距离单
    • GEOPOS key [member [member …]] 返回指定成员的地理位置信息
    • GEORADIUS key longitude latitude radius [M | KM ] 返回以指定位置为中心,指定距离为半径之内的数据
    • GEOADD location 116.310442 40.056564 itcast001
    • GEOADD location 116.307080 40.055798 courier_1 116.316688 40.057338 courier_2
    • GEOADD location 116.313772 40.053699 courier_3 116.311184 40.051204 courier_4
    • GEOADD location 116.309331 40.052172 courier_5 116.310937 40.050827 courier_6
    • GEOADD location 116.314077 40.056256 courier_7 116.316486 40.056098 courier_8
  1. hyperloglog 基数统计
  • 基数:数学上集合的元素个数,是不能重复的。
    UV(Unique visitor):是指通过互联网访问、浏览这个网页的自然人。访问的一个电脑客户端为一个访客,一天内同一个访客仅被计算一次。
  • Redis 2.8.9 版本更新了 hyperloglog 数据结构,是基于基数统计的算法。
  • hyperloglog 的优点是占用内存小,并且是固定的。存储 2^64 个不同元素的基数,只需要 12 KB 的空间。但是也可能有 0.81% 的错误率。
    int 4 b * 100000000 /1000 = 4*100000kb /1000 = 400M
    这个数据结构常用于统计网站的 UV。传统的方式是使用 set 保存用户的ID,然后统计 set 中元素的数量作为判断标准。
    但是这种方式保存了大量的用户 ID,ID 一般比较长,占空间,还很麻烦。我们的目的是计数,不是保存数据,所以这样做有弊端。但是如果使用 hyperloglog 就比较合适了。
    常用命令如下:
    • PFADD key [element [element …]] 将需要统计的成员保存到key中
    • PFCOUNT key 统计key的 成员数
  • HyperLogLog的使用场景主要包括以下几个方面:
    • 用户去重:使用HyperLogLog可以对海量的用户数据进行去重,快速地统计出不重复的用户数量。
    • 网站UV统计:使用HyperLogLog可以对网站的访问日志进行分析,统计出每天、每周、每月的独立访客数量。
    • 广告点击统计:使用HyperLogLog可以对广告的点击数据进行分析,统计出独立点击用户的数量,以及对多个广告进行并、交运算等。
    • 数据库查询优化:使用HyperLogLog可以对数据库中的数据进行去重,减少查询的数据量,提高查询效率。
    • 分布式计算:使用HyperLogLog可以在分布式系统中对数据进行去重、并、交等操作,以支持分布式计算。
  1. bitmap 位图
  • 1G = 1024 M 1M=1024kb 1kb = 1024b 1b=8bit。bitmap就是通过最小的单位bit来进行0或者1的设置,表示某个元素对应的值或者状态。一个bit的值,或者是0,或者是1;也就是说一个bit能存储的最多信息是2。bitmap 常用于统计用户信息比如活跃粉丝和不活跃粉丝、登录和未登录、是否打卡等。
    常用命令如下:
    • SETBIT key offset value 设置或清除存储在键处的字符串值中偏移处的位。
    • GETBIT key offset 获取存储与key指定偏移处的位
    • BITCOUNT key [start end [BYTE | BIT]] 统计key中所有设置了位的数量
  • bitmap原理
    • 我们为什么要选择bitmap? 因为只需要512M能表述2^32 的数据的是否存在!
      假设我们存储id , id是long类型 8字节 2^32*8 b /2^10 / 2^57 kb /2^10 = 2^47 m /2^10 = 2^5 G = 32G
    • bitmap是如何做到的呢?
      • bitmap的value其实是一个字符串。redis中value的最大是512M =2^9M *210=219 kb *2^10 = 2^29b * 8 = 232所以,总共有232个位来表示数据的是否存在。 也就是说可以表述42亿多的数据是否存在。
    • bitmap如何用一个位表示 id =asdfalskdfasdnflksajdfl 用户是否存在呢?
      • 我们应该设置2^32中的某一个位的值为1来表示 id=asdfalskdfasdnflksajdfl 是存在的。所以此时我们发现我们需要将一个字符串 id=asdfalskdfasdnflksajdfl 得换算成 一个数值 作为2^32次方中的索引。
    • 如何将一个字符串换算成一个数值呢?hash算法!!! hash算法 32位 = 4b = int = 2^32,
      ps:hash算法存在hash冲突,只会误判,不会漏判。

二、在Java中操作Redis

Redis的Java客户端
Redis 的 Java 客户端很多,常用的几种:

  • Jedis
  • Lettuce
  • Spring Data Redis

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。
重点讲解Spring Data Redis。

1. Spring Data Redis的使用

1.1. 介绍

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。
网址:https://spring.io/projects/spring-data-redis
在这里插入图片描述
Spring Boot提供了对应的Starter,maven坐标:

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

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:string数据操作 redisTemplate.opsForValue()
  • SetOperations:set类型数据操作 redisTemplate.opsForSet()
  • ZSetOperations:zset类型数据操作 redisTemplate.opsForZSet()
  • HashOperations:hash类型的数据操作 redisTemplate.opsForHash()
  • ListOperations:list类型的数据操作 redisTemplate.opsForList()

1.2. 环境搭建

导入Spring Data Redis的maven坐标

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

配置Redis数据源

sky:redis:host: localhostport: 6379database: 2

解释说明:

  • database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。可以通过修改Redis配置文件来指定数据库的数量。

1.3. 编写配置类,创建RedisTemplate对象

package com.sky.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
@Slf4j
public class RedisConfiguration {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){log.info("开始创建redis模板对象...");RedisTemplate redisTemplate = new RedisTemplate();//设置redis key、value的序列化器redisTemplate.setKeySerializer(new StringRedisSerializer());//value值支持中文正常显示redisTemplate.setValueSerializer(new FastJsonRedisSerializer<Object>(Object.class));//设置redis的连接工厂对象redisTemplate.setConnectionFactory(redisConnectionFactory);return redisTemplate;}
}

解释说明:

  • 当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别,故设置为StringRedisSerializer序列化器。
  • 不配置,默认注入
@Autowired
private RedisTemplate<String,String> redisTemplate;  //这里可以指定泛型@Autowired
//这个注入进行了序列化不会乱码
private StringRedisTemplate redisTemplate;  //这个也是redis注入的另一个实现类

在这里插入图片描述
在这里插入图片描述
RedisTemplate默认使用JDK的序列化机制,因此从程序中输入的字符串经过序列化看起来像是乱码;而StringRedisTemplate使用了String的序列化机制,因此有一种所见即所得的效果。

1.4. 通过RedisTemplate对象操作Redis

package com.sky.test;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedisTemplate(){System.out.println(redisTemplate);//string数据操作etOperations = redisTemplate.opsForZSet();}
}

测试

在这里插入图片描述
说明RedisTemplate对象注入成功,并且通过该RedisTemplate对象获取操作5种数据类型相关对象。
上述环境搭建完毕后,接下来,我们就来具体对常见5种数据类型进行操作。

1.5. 操作示例

	/*** 操作字符串类型的数据*/@Testpublic void testString(){// set get setex setnxredisTemplate.opsForValue().set("name","小明");String city = (String) redisTemplate.opsForValue().get("name");System.out.println(city);redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);redisTemplate.opsForValue().setIfAbsent("lock","1");redisTemplate.opsForValue().setIfAbsent("lock","2");}
	/*** 操作哈希类型的数据*/@Testpublic void testHash(){//hset hget hdel hkeys hvalsHashOperations hashOperations = redisTemplate.opsForHash();hashOperations.put("100","name","tom");hashOperations.put("100","age","20");String name = (String) hashOperations.get("100", "name");System.out.println(name);Set keys = hashOperations.keys("100");System.out.println(keys);List values = hashOperations.values("100");System.out.println(values);hashOperations.delete("100","age");}
	/*** 操作列表类型的数据*/@Testpublic void testList(){//lpush lrange rpop llenListOperations listOperations = redisTemplate.opsForList();listOperations.leftPushAll("mylist","a","b","c");listOperations.leftPush("mylist","d");List mylist = listOperations.range("mylist", 0, -1);System.out.println(mylist);listOperations.rightPop("mylist");Long size = listOperations.size("mylist");System.out.println(size);}
	/*** 操作集合类型的数据*/@Testpublic void testSet(){//sadd smembers scard sinter sunion sremSetOperations setOperations = redisTemplate.opsForSet();setOperations.add("set1","a","b","c","d");setOperations.add("set2","a","b","x","y");Set members = setOperations.members("set1");System.out.println(members);Long size = setOperations.size("set1");System.out.println(size);Set intersect = setOperations.intersect("set1", "set2");System.out.println(intersect);Set union = setOperations.union("set1", "set2");System.out.println(union);setOperations.remove("set1","a","b");}
	/*** 操作有序集合类型的数据*/@Testpublic void testZset(){//zadd zrange zincrby zremZSetOperations zSetOperations = redisTemplate.opsForZSet();zSetOperations.add("zset1","a",10);zSetOperations.add("zset1","b",12);zSetOperations.add("zset1","c",9);Set zset1 = zSetOperations.range("zset1", 0, -1);System.out.println(zset1);zSetOperations.incrementScore("zset1","c",10);zSetOperations.remove("zset1","a","b");}
/*** 通用命令操作*/@Testpublic void testCommon(){//keys exists type delSet keys = redisTemplate.keys("*");System.out.println(keys);Boolean name = redisTemplate.hasKey("name");Boolean set1 = redisTemplate.hasKey("set1");for (Object key : keys) {DataType type = redisTemplate.type(key);System.out.println(type.name());}redisTemplate.delete("mylist");}
//分页查询  项目示例
public PageResponse<RoleVo> findRolePage(RoleDto roleDto, int pageNum, int pageSize) {//设置keyString key = CacheConstant.RESOURCE_PREFIX+ roleDto.hashCode()+pageNum+pageSize;//查询String listStr = redisTemplate.opsForValue().get(key);if (StringUtils.isNotBlank(listStr)){return BeanUtil.toBean(listStr,PageResponse.class);}PageHelper.startPage(pageNum, pageSize);Page<Role> page = roleMapper.selectPage(roleDto);PageResponse<RoleVo> pageResponse = PageResponse.of(page, RoleVo.class);//存入redisredisTemplate.opsForValue().set(key, JSON.toJSONString(pageResponse),30, TimeUnit.MINUTES);return pageResponse;}

2. Spring Cache的使用

2.1. 介绍

前言:

  • 在我们查询部门数据的时候,特别是树形结构,要把所有的属性结构数据都展示出来,这个是会对数据库的访问造成一定的压力,并且从数据库查询效率也不是很高,所以我们通常都会添加缓存来提升效率

  • 添加缓存的基本逻辑:
    在这里插入图片描述

  • Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

  • Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如:

    • EHCache
    • Caffeine
    • Redis(常用)
  • 常用注解
    在这里插入图片描述

2.2. 使用

  1. 集成环境
    在这里插入图片描述
  2. 在引导类上添加EnableCaching注解
    在这里插入图片描述
  3. 配置application.yml文件配置缓存对象
# 缓存相关配置
# 这里如果启用redis作为缓存那么就写redis,如果用ehcache就写ehcache
spring: cache: type: redis

2.3. 注解详解

  1. @CachePut 说明:
    • 作用: 将方法返回值,放入缓存
    • value: 缓存的名称, 每个缓存名称下面可以有很多ke
    • key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法
  • 在目标方法上加注解@CachePut,用法如下:
	/*** CachePut:将方法返回值放入缓存* value:缓存的名称,每个缓存名称下面可以有多个key* key:缓存的key*/@PostMapping@CachePut(value = "userCache", key = "#user.id")//key的生成:userCache::1public User save(@RequestBody User user){userMapper.insert(user);return user;}

说明:key的写法如下

  • user.id : #user指的是方法形参的名称, id指的是user的id属性 ,也就是使用user的id属性作为key ;
  • result.id : #result代表方法返回值,该表达式代表以返回对象的id属性作为key ;
  • p0.id:#p0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key
  • a0.id:#a0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key
  • root.args[0].id:#root.args[0]指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key
  1. @Cacheable注解
    • 作用: 在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
    • value: 缓存的名称,每个缓存名称下面可以有多个key
    • key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法
  • 使用示例
	/*** Cacheable:在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,	  *调用方法并将方法返回值放到缓存中* value:缓存的名称,每个缓存名称下面可以有多个key* key:缓存的key*/@GetMapping@Cacheable(cacheNames = "userCache",key="#id")public User getById(Long id){User user = userMapper.getById(id);return user;}
  • 多条件使用:
@Cacheable(value = "userCache",key="#userDto.hashCode()",unless = "#result.size() == 0")
//当条件比较冗余时,我们可以将条件封装,使用其封装对象的hash值当做key参数实体内容一致,则哈希值一致
public List<User> getList(UserDto userDto){List<User> list = userMapper.getList("%" + userDto.getName() + "%", userDto.getAge());return list;
}

如果返回结果为空,则不缓存unless = "#result = = null"或unless = “#result.size() = = 0” unless条件为true则不存入缓存

  1. @CacheEvict注解
    • 作用: 清理指定缓存
    • value: 缓存的名称,每个缓存名称下面可以有多个key
    • key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法
    • 使用示例
	@DeleteMapping@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据public void deleteById(Long id){userMapper.deleteById(id);}@DeleteMapping("/delAll")@CacheEvict(cacheNames = "userCache",allEntries = true)//删除userCache下所有的缓存数据public void deleteAll(){userMapper.deleteAll();}
  1. @Caching注解
    • 作用: 组装其他缓存注解
    • cacheable 组装一个或多个@Cacheable注解
    • put 组装一个或多个@CachePut注解
    • evict 组装一个或多个@CacheEvict注解
    • 使用示例
@Caching(cacheable = {@Cacheable(value = "userCache",key = "#id")},put = {@CachePut(value = "userCache",key = "#result.name"),@CachePut(value = "userCache",key = "#result.age")}
)
public User getById(Long id){User user = userMapper.getById(id);if(user == null){throw new RuntimeException("用户不存在");}return user;
}

当调用getById方法之后,首先到缓存中根据id查询数据,如果查询不成功还是会到数据库中找数据,同时会再往redis中set两个缓存,key分别是name和age

  1. 项目使用示例
    • 过期时间等设置需要在配置文件中设置,不如Spring Data Redis灵活
@Service
@Transactional
public class ResourceServiceImpl implements ResourceService {/*** 多条件列表查询* @param resourceDto* @return*/@Cacheable(value = CacheConstant.RESOURCE_LIST ,key ="#resourceDto.hashCode()")@Overridepublic List<ResourceVo> getList(ResourceDto resourceDto) {}/*** 封装资源的树形结构** @param resourceDto* @return*/@Cacheable(value = CacheConstant.RESOURCE_TREE )@Overridepublic TreeVo resourceTreeVo(ResourceDto resourceDto) {}/*** 添加资源* @param resourceDto*/@Caching(evict = {@CacheEvict(value = CacheConstant.RESOURCE_LIST ,allEntries = true),@CacheEvict(value = CacheConstant.RESOURCE_TREE ,allEntries = true)})@Overridepublic void createResource(ResourceDto resourceDto) {}/*** 修改资源* @param resourceDto*/@Caching(evict = {@CacheEvict(value = CacheConstant.RESOURCE_LIST ,allEntries = true),@CacheEvict(value = CacheConstant.RESOURCE_TREE ,allEntries = true)})@Overridepublic void updateResource(ResourceDto resourceDto) {}/*** 启用禁用* @param resourceVo* @return*/@Caching(evict = {@CacheEvict(value = CacheConstant.RESOURCE_LIST ,allEntries = true),@CacheEvict(value = CacheConstant.RESOURCE_TREE ,allEntries = true)})@Overridepublic void isEnable(ResourceVo resourceVo) {}/*** 删除菜单* @param resourceNo*/@Caching(evict = {@CacheEvict(value = CacheConstant.RESOURCE_LIST ,allEntries = true),@CacheEvict(value = CacheConstant.RESOURCE_TREE ,allEntries = true)})@Overridepublic void deleteByResourceNo(String resourceNo) {}}

3. Spring Data Redis常用API

  1. RedisTemlate相关方法体系
    1. RedisTemlate类主要提供opsForValue(), opsForHash(), opsForList(), opsForSet(), opsForZSet() 等方法来获取特定数据类型的操作接口。这些方法返回相应的操作对象。
    2. ValueOperations<K, V>,HashOperations<K, HK, HV>,ListOperations<K, V>,SetOperations<K, V>接口的实现这些对象提供了对该数据类型进行操作的方法,其主要为在Redis中存储和获取内容。
    3. 而上述各个对象都实现了RedisOperations 接口,这个接口中提供了更多的Redis的具体操作,接口详情见下面
    4. 其他常用方法
      1. keys(String Pattern)获取当前所有的key(Pattren为正则表达式,模糊匹配需要使用通配符即* )
      2. delete(String Pattern/Collection keyLsit)删除当前redis中符合条件的key-value
      3. remove()删除当前redis中所有的key-value
  2. RedisOperations接口
    在这里插入图片描述
Long remainTimeToLive = redisTemplate.opsForValue().getOperations().getExpire(jwtTokenKey, TimeUnit.SECONDS);

Long remainTimeToLive = redisTemplate.opsForValue().getOperations().getExpire(jwtTokenKey, TimeUnit.SECONDS);
这段代码是用来获取 Redis 中某个键的剩余生存时间(TTL,Time To Live)。具体来说,redisTemplate.opsForValue().getOperations().getExpire(jwtTokenKey) 会返回键 jwtTokenKey 的剩余过期时间(以秒为单位),如果键不存在或者没有设置过期时间,则会返回一个特定的值。
让我们分解一下这段代码:

  1. redisTemplate.opsForValue():这一步获取了 ValueOperations 的实例,它是用来操作字符串类型的键值对的。
  2. getOperations():由于 ValueOperations 实现了 Operations 接口,因此可以通过调用 getOperations() 来获取一个 RedisOperations 的实例,这个实例提供了更多的 Redis 操作方法,包括获取键的过期时间。
  3. getExpire(jwtTokenKey):这个方法实际上获取指定键的过期时间。返回值是一个 Long 类型,表示键还有多少秒过期。如果键不存在或者没有设置过期时间,则返回 -2L;如果键存在但是没有设置过期时间,则返回 -1L。
    RedisOperations详解
    RedisOperations 接口是 Spring Data Redis 提供的一个基础接口,它提供了一系列基本的 Redis 操作方法。虽然通常我们不会直接使用 RedisOperations,而是使用它的子接口如 BoundValueOperations, BoundHashOperations, BoundListOperations, BoundSetOperations, BoundZSetOperations 或者 ValueOperations, HashOperations, ListOperations, SetOperations, ZSetOperations 等来执行更具体的 Redis 操作。然而,RedisOperations 本身也提供了一些通用的操作方法。下面是一些常用的方法及其说明:
  • 基本操作
    1. void delete(K key)
      删除给定的键。
    2. void delete(Collection keys)
      删除给定集合中的所有键。
    3. boolean exists(K key)
      检查给定的键是否存在。
    4. K randomKey()
      随机返回一个键。
    5. void rename(K oldKey, K newKey)
      重命名给定的键。
    6. void renameIfAbsent(K oldKey, K newKey)
      如果新的键不存在则重命名给定的键。
    7. Long expire(K key, long timeout, TimeUnit unit)
      设置键的过期时间。
    8. Long persist(K key)
      移除键的过期时间。
    9. Long getExpire(K key, TimeUnit unit)
      获取键的剩余过期时间。
  • 批量操作
    1. Map<K, Boolean> executePipelined(RedisCallback callback)
      批量执行命令并返回结果。
    2. Map<K, Boolean> executePipelined(RedisCallback callback, K… keys)
      批量执行针对特定键的命令并返回结果。
    3. Map<K, Boolean> executePipelined(RedisCallback callback, Collection keys)
      批量执行针对特定键集合的命令并返回结果。
  • 事务支持
    1. void multi()
      开始一个事务。
    2. List exec()
      执行事务中的所有命令。
    3. void discard()
      取消事务中的所有命令。
  • 其他
    1. String debug()
      返回调试信息。
    2. void shutdown()
      关闭 Redis 服务器。
    3. String info()
      返回关于 Redis 服务器运行状态的信息。

示例:

// 删除键
redisTemplate.delete("myKey");// 检查键是否存在
boolean exists = redisTemplate.hasKey("myKey");// 获取键的过期时间
Long ttl = redisTemplate.getExpire("myKey", TimeUnit.SECONDS);// 设置键的过期时间
redisTemplate.expire("myKey", 60, TimeUnit.SECONDS);// 开始一个事务
redisTemplate.multi();// 执行事务中的所有命令
List<Object> results = redisTemplate.exec();// 取消事务中的所有命令
redisTemplate.discard();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143069.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux入门学习:git

文章目录 1. 创建仓库2. 仓库克隆3. 上传文件4. 相关问题4.1 git进程阻塞4.2 git log4.3 上传的三个步骤在做什么 本文介绍如何在Linux操作系统下简单使用git&#xff0c;对自己的代码进行云端保存。 1. 创建仓库 &#x1f539;这里演示gitee的仓库创建。 2. 仓库克隆 &…

Zookeeper 3.8.4 安装和参数解析

安装 zookeeper 之前必须先安装 JDK&#xff0c;有关Linux环境JDK可以参考我以前写的博文 1、关于Linux服务器配置java环境遇到的问题 2、Linux环境安装openJDK 3、Centos7.3云服务器上安装Nginx、MySQL、JDK、Tomcat环境 文章目录 1. zookeeper 安装2. 参数解析 1. zookeeper …

VScode快速配置c++(菜鸟版)

1.vscode是什么 Visual Stdio Code简称VS Code&#xff0c;是一款跨平台的、免费且开源的现代轻量级代码编辑器&#xff0c;支持几乎 主流开发语言的语法高亮、智能代码补全、自定义快捷键、括号匹配和颜色区分、代码片段提示、代码对比等特性&#xff0c;也拥有对git的开箱即…

[乱码]确保命令行窗口与主流集成开发环境(IDE)统一采用UTF-8编码,以规避乱码问题

文章目录 一、前言二、命令行窗口修改编码为UTF-8三、Visual Studio 2022修改编码为UTF-8四、Eclipse修改编码为UTF-8五、DevCPP修改编码为UTF-8六、Sublime Text修改编码为UTF-8七、PyCharm、IDEA、VS Code及Python自带解释器修改编码为UTF-8 一、前言 在学习的征途中&#x…

如何通过 4 种方法恢复 Mac 上删除/未保存的 Excel 文件

您花了数小时在 MacBook 上处理 Excel 工作簿&#xff0c;但现在它不见了。或者&#xff0c;当您退出 Excel 文件时&#xff0c;您无意中选择了“不保存”。这是否意味着您的所有努力都白费了&#xff1f;本文系统地解释了如何在 Mac 上恢复丢失的 Excel 文件。使用我们的 4 种…

如何在Android上实现RTSP服务器

技术背景 在Android上实现RTSP服务器确实是一个不太常见的需求&#xff0c;因为Android平台主要是为客户端应用设计的。在一些内网场景下&#xff0c;我们更希望把安卓终端或开发板&#xff0c;作为一个IPC&#xff08;网络摄像机&#xff09;一样&#xff0c;对外提供个拉流的…

Linux学习记录十四----------线程的创建和回收

文章目录 五、Linux线程1.守护进程1.1.守护进程的特点1.2.进程组1.3会话1.4创建守护进程模型 2.线程的概念3.线程的创建及相关函数3.1.创建线程‐‐pthread_create3.2.单个线程退出 --pthread_exit3.3.阻塞等待线程退出&#xff0c;获取线程退出状态--pthread_join3.4.线程分离…

无限制使用OpenAI最新o1-mini、o1-preview模型:经济高效的AI推理模型

OpenAI 最新推出的 o1 模型是该公司推理模型家族的首位成员&#xff0c;它通过创新的“思维链”训练模式&#xff0c;显著提升了逻辑推理和问题解决的能力。o1 模型在编程竞赛问题、数学奥林匹克资格赛以及物理、生物和化学问题的基准测试中表现出色&#xff0c;甚至在某些领域…

学成在线练习(HTML+CSS)

准备工作 项目目录 内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等 1.由于元素具有一些默认样式&#xff0c;可能是我们写网页过程中根本不需要的&#xff0c;所有我们可以在写代码之前就将其清除 base.css /* 基础公共样式&#xff1a;清除…

Tongweb7启动的时候显示要输入java参数(by lqw)

问题描述&#xff1a; 启动tongweb7的时候&#xff0c;提示要输入java参数&#xff0c;如下图所示&#xff1a; 原因&#xff1a; tongweb安装目录bin目录下的external.vmoptions文件改动&#xff0c;在# 符号后加多了一个空格。 external.vmoptions记录的是启动参数&#xf…

【读书】原则

后面的 太长了&#xff0c;而且太多了 我看作者 49年的 0多岁的老人的谆谆教诲 太多了 一下子吃不消 分为 生活原则 和 工作原则 倡导 人要以 原则而活 要做到极度透明 极度求真和极度透明&#xff1a;在软件开发中&#xff0c;对事实的执着追求和对信息的透明度是至关重要的。…

论文阅读 - SELF-REFINE: Iterative Refinement with Self-Feedback

https://arxiv.org/pdf/2303.17651 目录 Abstract Introduction 2 Iterative Refinement with SELF-REFINE Evaluation 3.1 Instantiating SELF-REFINE 3.2 Metrics 3.3 Results Abstract 与人类一样&#xff0c;大型语言模型&#xff08;LLMs&#xff09;并非总能在首次…

【刷题日记】螺旋矩阵

54. 螺旋矩阵 这个是一道模拟题&#xff0c;但我记得我大一第一次做这道题的时候真的就是纯按步骤模拟&#xff0c;没有对代码就行优化&#xff0c;导致代码写的很臃肿。 有这么几个地方可以改进。 看题目可以知道最终的结果一定是rows*cols个结点,所以只需要遍历rows*cols次…

java十进制码、六进制码和字符码的转换

一、字符转换为ASCII码&#xff1a; int i(int)1; 二、ASCII码转换为字符&#xff1a; char ch (char)40; 三、十六进制码转换为字符&#xff1a; char charValue (char)\u0040; package week3;public class check_point4_8 {public static void main(String[] args) {S…

Java 性能调优:优化 GC 线程设置

垃圾回收器使用一组称为 GC 线程的线程来执行回收工作。有时 JVM 可能会分配过多或过少的 GC 线程。本文将讨论 JVM 为什么会出现这种情况、其影响以及可能的解决方案。 1 咋查找应用程序的 GC 线程数量 进行线程转储分析来确定应用程序的 GC 线程数量&#xff1a; 从生产服…

【算法思想·二叉搜索树】基操篇

本文参考labuladong算法笔记[二叉搜索树心法&#xff08;基操篇&#xff09; | labuladong 的算法笔记] 1、概述 我们前文 东哥带你刷二叉搜索树&#xff08;特性篇&#xff09; 介绍了 BST 的基本特性&#xff0c;还利用二叉搜索树「中序遍历有序」的特性来解决了几道题目&am…

MathType7.9绿色和谐版激活补丁包下载

MathType7.9中文版&#xff1a;让你的数学公式更酷炫✨ 嘿&#xff0c;亲爱的数学迷们&#xff01;今天我要给你们安利一款超级炫酷的数学公式编辑器——MathType7.9中文版。这款软件不仅能让你轻松输入各种复杂的数学公式&#xff0c;还能让你的公式看起来更加酷炫哦&#xf…

Java项目——苍穹外卖(二)

Redis 简介 Redis是一个基于内存的key-value结构数据库 基于内存存储&#xff0c;读写性能高适合存储热点数据&#xff08;热点商品、资讯、新闻&#xff09;企业应用广泛 基础操作 启动 在redis安装目录中打开cmd&#xff0c;输入如上图指令即可启动&#xff0c;按下crtl…

【嘉立创EDA】画PCB板中为什么要两面铺铜为GND,不能一面GND一面VCC吗?

在新手画板子铺铜时&#xff0c;经常会铺一面GND一面VCC。但一般情况下我们不会这样铺铜。下面将详细分析为什么要两面铺铜为GND&#xff0c;而不是一面GND一面VCC的原因&#xff1a; 提高散热能力 金属导热性&#xff1a;金属具有良好的导热性&#xff0c;铺铜可以有效分散PCB…

unity的学习

因为需要构建一个三维物理环境,所以学习了unity,半天就可以,非常简单清晰 1.安装 去官网下载unity hub . 然后需要下载editor,但注意已经有了vs2022就不要再下一次了,下的时候会全放c盘,再安装.c盘都装不下了. 如果美游vs2022,就先自己把vs2022安装好,再安装unity hub.(其实不…