Redis 是一个基于内存的键值数据库
安装
Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装_明金同学的博客-CSDN博客

出现上面代表安装成功了

redis 一共有 16 个库

安装后 再安装图形化界面
图形界面十分方便去使用
redis 是 键值对的数据库 key 一般是 string 类型 但是 value 的类型 多种多样
String 类型
- set 添加或者修改一个已经存在的String类型的键值对
- get 获取到对应 key 的 value
- mset 批量添加多个 String 类型的 键值对
- mget 获取到所有 key 的 value
- incr 让一个整型的 key 自增 1
- incrby 让一个整型的 key 自增 并且指定 步长
- incrbyfloat 让一个 浮点 类型 的数字自增并且指定步长
- setnx 添加一个String 类型的 键值对 前提时 这个 key 不存在 否则不执行
- setex 添加一个 String 类型的键值对 并且指定有效期
redis 的 key 允许 有多个 单词 形成 层级结构 多个单词之间 用 : 隔开
类似于 java 中的 HashMap 结构 Hash 结构 可以将对象中的 每个 字段 独立存储 可以针对 单个字段做 CRUD
- hset key field value 添加或者修改 hash 类型 key 的 field 的值
- hset key field 获取一个hash类型key 的 field 的值
- hmset 批量添加多个 hash 类型 key 的 field 的值
- hmget 批量获取 多个 hash 类型 key 中的 所有 field 和 value
- hgetall 获取一个hash类型的key中的所有的field 和 value
- hkeys 获取一个hash 类型 key 中 所有的 field
- hvals 获取一个hash 类型 的 key 中的 所有的 value
- hincrby 让一个hash 类型 key 字段值 自增 并 指定步长
- hsetnx 添加一个 hash 类型的 key 的 field 值 前提是这个 field 不存在 否则不执行


redis 中 的 list 类型 与 java 中的 LinkedList 类似 可以看作 是一个 双向链表 结构 既可以支持 正向检索 也可以 支持 反向 检索
特征也与 LinkedList 类似
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
- lpush 向 列表 左侧 插入 一个 或者 多个 元素
- lpop 移除 并 返回 列表 左侧 第一个元素 没有则返回 nil
- rpush 向 列表 右侧 插入 一个或者多个 元素
- rpop 移除 并且 返回 列表 右侧 的 第一个元素
- lrange 返回一段 下标 范围 内 的 所有 元素
- blpop 和 brpop 与 lpop 和 rpop 类似 只不过 在 没有 元素 时 等待 指定时间 而不是直接 返回 nil
redis 的 set 结构 与 java 中的 HashSet 类似 可以看作 是一个 value 为 null 的 HashMap
- 无序
- 元素 不可 重复
- 查找快
- 支持交集 并集 差集 等 功能
- sadd 向 set 中 添加 一个多个元素
- srem 移除 set 中的指定元素
- scard 返回 set 中元素的个数
- sismemery 判断 一个元素 是否存在 于 set 中
- smemers 获取 set 中 所有 元素
- sinter 求 集合 的 交集
- sdiff 求 集合 的 差集
- sunion 求 集合 的并集

SortedSet 类型
redis 中的 SortedSet 是一个可排序 的 set 集合 与 java 中的 TreeSet 有些类似 但是底层 数据结构 却 差别 很大 SortedSet 中 每一个元素 都 带有 一个 score 属性 , 可以基于 score 属性 对元素 排序 。底层 的 实现 是一个 跳表 加 hash 表
- 可排序
- 元素 不重复
- 查询速度快
- zadd 添加 一个 或 多个元素 到 sortedset 中 如果已经存在 则 更新其 score 值
- zrem 删除 sortedset 中的一个指定元素
- zcore 获取 sortedset 中 指定 元素 的score值
- zrank 获取 sortedset 中的元素个数
- zcard 获取 sortedset 中元素个数
- zcount 统计score 值在给定范围 内 所有 元素 的个数
- zincrby 让sortedset 的指定元素自增 步长 为指定的 increment 值
- zrange 按照score排序后 获取指定排名 范围内的元素
- zrangebyscore 按照 score 排序后 获取指定 score 范围内 的 元素
- zdiff zinter zunion 求差集 交集 并集
默认排名 都是 升序 如果还想要降序 在命令的后面 添加 rev 即可

GEO 类型
BitMap 类型
HyperLog 类型
- keys 查看符合模板的所有key 不建议在生产环境使用
- del 删除一个指定的key
- exists 判断该 key 是否存在
- expire 设置一个key的有效期 有效期到了后key会自动删除 单位是秒
- TTL 查看一个key的剩余有效期 当TTL为 -1 时 说明该 数据 永久有效期 为 -2 时表示已经过期

Jedis 是 redis 在java语言上的 客户端
使用:
新建maven项目
依赖:
- <dependency>
- <groupId>redis.clientsgroupId>
- <artifactId>jedisartifactId>
- <version>4.3.1version>
- dependency>
测试代码:
- package com.lxh;
-
- import org.junit.jupiter.api.AfterEach;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.Test;
- import redis.clients.jedis.Jedis;
-
- public class JedisTest {
- private Jedis jedis;
-
- @BeforeEach
- void setUp()
- {
- //建立连接
- jedis=new Jedis("127.0.0.1",6379);
- // 如果你有设置密码 就要加下面这句话 我是并没有 设置密码的
- // jedis.auth("123456");
- jedis.select(0);
- }
-
- @Test
- void testString ()
- {
- String result=jedis.set("name","李泽言");
- System.out.println("result ="+result);
-
- String name = jedis.get("name");
- System.out.println("name="+name);
- }
-
- @AfterEach
- void tearDown()
- {
- if (jedis!=null)
- {
- jedis.close();
- }
- }
- }

Jedis 本身 是 线程 不安全 的 ,并且 频繁 的 创建 和 销毁 会有性能损耗 因此 我们推荐大家 使用 Jedis 连接池 代替 Jedis 的 直连 方式
代码:
- package com.lxh;
-
- import redis.clients.jedis.Jedis;
- import redis.clients.jedis.JedisClientConfig;
- import redis.clients.jedis.JedisPool;
- import redis.clients.jedis.JedisPoolConfig;
-
- public class JedisConnectionFactory {
-
- private static JedisPool jedisPool = new JedisPool();
-
- static {
- JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
- //设置最大连接数
- jedisPoolConfig.setMaxTotal(8);
- //设置最大空闲数
- jedisPoolConfig.setMaxIdle(8);
- //设置最小空间数
- jedisPoolConfig.setMinIdle(0);
-
- jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,1000);
-
- }
-
- public static Jedis getJedis(){
- return jedisPool.getResource();
- }
- }

运行结果:

SpringDataRedis 是 Spring 中数据 操作 的 模块 包含 各种 对 数据库 的 集成 其中对 Redis 的集成 模块 就叫做 SpringDataRedis
- 提供了对不同 Redis 客户端的整合
- 提供了 RedisTemplate 统一 API 来操作 Redis
- 支持 Redis 的发布 订阅 模型
- 支持 Redis 哨兵 和 Redis 集群
- 支持 基于 Lettuce 的响应式编程
- 支持 基于 JDK JSON 字符串 Spring 对象 的数据 序列化 及 反序列化
- 支持基于 Redis 的 JDKCollection 实现
SpringDataRedis 中提供了 对 RedisTamplate 工具类 其中封装了 对各种 Redis 的操作 并且将不同数据类型 的 操作 API 封装到了 不同的类中

新建一个 基于 maven 的 spring 的项目
引入 spring-boot-starter-data-redis 依赖
- "1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
- <parent>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-parentartifactId>
- <version>3.1.4version>
- <relativePath/>
- parent>
- <groupId>com.examplegroupId>
- <artifactId>redisData-demoartifactId>
- <version>0.0.1-SNAPSHOTversion>
- <name>redisData-demoname>
- <description>redisData-demodescription>
- <properties>
- <java.version>17java.version>
- properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-data-redisartifactId>
- <version>3.0.4version>
- dependency>
-
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- <version>1.18.26version>
- <optional>trueoptional>
- dependency>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-testartifactId>
- <version>3.1.0version>
- <scope>testscope>
- dependency>
-
- <dependency>
- <groupId>org.apache.commonsgroupId>
- <artifactId>commons-pool2artifactId>
- <version>2.11.1version>
- dependency>
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-maven-pluginartifactId>
- <version>3.1.4version>
- <configuration>
- <excludes>
- <exclude>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- exclude>
- excludes>
- configuration>
- plugin>
- plugins>
- build>
-
- project>
在 application.properties 下 写入这些
- #这里是地址 localhost 对应 的 就是 127.0.0.1
- spring.data.redis.host=localhost
- #这里是端口号
- spring.data.redis.port=6379
- #如果你需要设置密码,就写这个 否则就不写
- #spring.data.redis.password=12345
- #当前使用的是哪一个 数据库 一共 是 下标 0 - 15
- spring.data.redis.database=1
- #是否使用线程池
- spring.data.redis.lettuce.pool.enabled=true
- #最大活动线程池个数
- spring.data.redis.lettuce.pool.max-active=8
- #最长等待时间 以毫秒 为单位
- spring.data.redis.lettuce.pool.max-wait=2000
- #这是最大 空闲 连接池 个数
- spring.data.redis.lettuce.pool.max-idle=8
-
然后就是测试
- package com.example.redisdatademo;
-
- 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.RedisTemplate;
-
- @SpringBootTest
- class RedisDataDemoApplicationTests {
-
- @Autowired
- private RedisTemplate redisTemplate;
-
- @Test
- void contextLoads() {
- }
-
- @Test
- void testString()
- {
- //写入一条 String 数据
- redisTemplate.opsForValue().set("user","lizeyan");
- String user = (String) redisTemplate.opsForValue().get("user");
- System.out.println("user : "+user);
- }
-
- }
运行 testString 能正确输出即可
SpringDataRedis 的 序列化方式
RedisTemplate 可以 接收任意 Object 作为 值 写入Redis 只不过 写入前会把Object序列化 为字节形式 默认是采用JDK序列化的 ,得到的结构就会变成 这样

缺点 可读性差,内存占用大
我们可以重写方法 来修改 存入 redis 的数据状态
- package com.example.redisdatademo;
-
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.ObjectMapper;
- 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.GenericJackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.RedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
-
- import java.net.UnknownHostException;
-
- @Configuration
- public class redisDataConfig {
-
- @Bean
- public RedisTemplate
redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException - {
-
- RedisTemplate
redisTemplate = new RedisTemplate<>(); - redisTemplate.setConnectionFactory(redisConnectionFactory);
-
- // 设置key和hashKey的序列化器为String类型
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashKeySerializer(new StringRedisSerializer());
-
- // 设置value和hashValue的序列化器为Jackson2JsonRedisSerializer
- Jackson2JsonRedisSerializer
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jsonRedisSerializer.setObjectMapper(objectMapper);
-
- redisTemplate.setValueSerializer(jsonRedisSerializer);
- redisTemplate.setHashValueSerializer(jsonRedisSerializer);
-
- redisTemplate.afterPropertiesSet();
- return redisTemplate;
-
- //
- // //创建 Template
- // RedisTemplate
redisTemplate=new RedisTemplate<>(); - // //设置连接工厂
- // redisTemplate.setConnectionFactory(redisConnectionFactory);
- // //设置序列化工具
- // GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
- //
- // //key 和 hashKey 采用 string 序列化
- // redisTemplate.setKeySerializer(RedisSerializer.string());
- // redisTemplate.setHashKeySerializer(RedisSerializer.string());
- //
- // //value 和 hashValue 采用 string 序列化
- // redisTemplate.setValueSerializer(RedisSerializer.string());
- // redisTemplate.setHashValueSerializer(RedisSerializer.string());
- //
- // return redisTemplate;
- }
-
- }
要导入依赖
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.15.1version>
- dependency>
测试输出


如果按照上面这个方式 那么会需要额外的存储空间来存储 这个类的路径 为了节省 内存空间 我们并不会 使用 JSON 序列化 来处理 value 而是 使用 String 序列化 器 。要求 只能存储 String 类型的 key 和 value ,当需要 存储 java 对象 时 手动 完成对象 的序列化 和 反序列化。
Spring 默认提供了一个 StringRedisTemplate 类 它的 key 和 value 的序列化方式 默认就是String 方式 省去了 我们自定义 RedisTemplate 的过程
- package com.example.redisdatademo;
-
- import com.example.bean.User;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
- 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.RedisTemplate;
- import org.springframework.data.redis.core.StringRedisTemplate;
-
- @SpringBootTest
- class RedisDataDemoApplicationTests {
-
- @Autowired
- private RedisTemplate
redisTemplate; -
- @Autowired
- private StringRedisTemplate stringRedisTemplate;
-
- //JSON工具
- private static final ObjectMapper mapper=new ObjectMapper();
-
- @Test
- void contextLoads() {
- }
-
- @Test
- void testString()
- {
- //写入一条 String 数据
- redisTemplate.opsForValue().set("user","lizeyan");
- String user =(String) redisTemplate.opsForValue().get("user");
- System.out.println("user : "+user);
- }
-
- @Test
- void testObject()
- {
- redisTemplate.opsForValue().set("user:xm",new User("许墨",26));
- User newUser=(User) redisTemplate.opsForValue().get("user:xm");
- System.out.println(newUser);
- }
-
- @Test
- void testStringTemplate() throws JsonProcessingException {
- //准备对象
- User user=new User("helios",22);
-
- //手动序列化
- String json=mapper.writeValueAsString(user);
- //写入一条数据到 redis
- stringRedisTemplate.opsForValue().set("user:zql",json);
-
- //读取数据
- String val=stringRedisTemplate.opsForValue().get("user:zql");
-
- //反序列化
- User newUser=mapper.readValue(val,User.class);
- System.out.println("user : "+newUser);
- }
-
- }
运行 testStringTemplate 就可以了 我们可以发现这个是没有类的路径的

