• 2023/9/24总结


    Redis

    Redis 是一个基于内存的键值数据库

    安装

    Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装_明金同学的博客-CSDN博客

    出现上面代表安装成功了

    redis 一共有 16 个库

    安装后 再安装图形化界面

    图形界面十分方便去使用

    redis数据结构介绍

    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 类型的键值对  并且指定有效期

    key 的结构  

    redis 的 key 允许 有多个 单词 形成 层级结构  多个单词之间 用  :  隔开  

    Hash 类型

    类似于  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 不存在 否则不执行

    List  类型

    redis 中 的 list 类型 与 java 中的 LinkedList 类似  可以看作 是一个 双向链表 结构 既可以支持 正向检索 也可以 支持 反向 检索

    特征也与 LinkedList 类似 

    • 有序
    • 元素可以重复 
    • 插入和删除快
    • 查询速度一般
    • lpush  向 列表 左侧 插入 一个 或者 多个 元素
    • lpop 移除 并 返回 列表 左侧 第一个元素 没有则返回  nil
    • rpush  向 列表 右侧 插入 一个或者多个 元素
    • rpop 移除 并且 返回 列表 右侧 的 第一个元素
    • lrange  返回一段 下标 范围 内 的 所有 元素
    • blpop 和 brpop  与 lpop 和 rpop 类似 只不过 在 没有 元素 时 等待 指定时间 而不是直接 返回 nil

    Set   类型

    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 类型

    Redis 通用命令

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

    Jedis 的 使用

    Jedis 是 redis 在java语言上的 客户端

    Java guide | Redis

    使用:

    新建maven项目

    依赖:

    1. <dependency>
    2. <groupId>redis.clientsgroupId>
    3. <artifactId>jedisartifactId>
    4. <version>4.3.1version>
    5. dependency>

    测试代码:

    1. package com.lxh;
    2. import org.junit.jupiter.api.AfterEach;
    3. import org.junit.jupiter.api.BeforeEach;
    4. import org.junit.jupiter.api.Test;
    5. import redis.clients.jedis.Jedis;
    6. public class JedisTest {
    7. private Jedis jedis;
    8. @BeforeEach
    9. void setUp()
    10. {
    11. //建立连接
    12. jedis=new Jedis("127.0.0.1",6379);
    13. // 如果你有设置密码 就要加下面这句话 我是并没有 设置密码的
    14. // jedis.auth("123456");
    15. jedis.select(0);
    16. }
    17. @Test
    18. void testString ()
    19. {
    20. String result=jedis.set("name","李泽言");
    21. System.out.println("result ="+result);
    22. String name = jedis.get("name");
    23. System.out.println("name="+name);
    24. }
    25. @AfterEach
    26. void tearDown()
    27. {
    28. if (jedis!=null)
    29. {
    30. jedis.close();
    31. }
    32. }
    33. }

    Jedis 连接池

    Jedis 本身 是 线程 不安全 的 ,并且 频繁 的 创建 和 销毁 会有性能损耗  因此 我们推荐大家 使用 Jedis 连接池 代替 Jedis 的 直连 方式

    代码:

    1. package com.lxh;
    2. import redis.clients.jedis.Jedis;
    3. import redis.clients.jedis.JedisClientConfig;
    4. import redis.clients.jedis.JedisPool;
    5. import redis.clients.jedis.JedisPoolConfig;
    6. public class JedisConnectionFactory {
    7. private static JedisPool jedisPool = new JedisPool();
    8. static {
    9. JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
    10. //设置最大连接数
    11. jedisPoolConfig.setMaxTotal(8);
    12. //设置最大空闲数
    13. jedisPoolConfig.setMaxIdle(8);
    14. //设置最小空间数
    15. jedisPoolConfig.setMinIdle(0);
    16. jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,1000);
    17. }
    18. public static Jedis getJedis(){
    19. return jedisPool.getResource();
    20. }
    21. }

    运行结果:

    SpringDataRedis

    SpringDataRedis 是 Spring 中数据 操作 的 模块 包含 各种 对 数据库 的 集成 其中对 Redis 的集成 模块 就叫做 SpringDataRedis 

    Spring Data Redis

    •  提供了对不同 Redis 客户端的整合
    • 提供了 RedisTemplate 统一 API 来操作 Redis
    • 支持 Redis 的发布 订阅 模型
    • 支持 Redis 哨兵 和 Redis 集群
    • 支持 基于 Lettuce 的响应式编程
    • 支持 基于 JDK  JSON  字符串  Spring 对象 的数据 序列化 及 反序列化
    • 支持基于 Redis 的 JDKCollection 实现

    SpringDataRedis 中提供了 对 RedisTamplate 工具类 其中封装了 对各种 Redis 的操作  并且将不同数据类型 的 操作 API 封装到了 不同的类中

    SpringDataRedis 使用步骤

    新建一个 基于 maven 的 spring 的项目

    引入 spring-boot-starter-data-redis 依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <parent>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <version>3.1.4version>
    9. <relativePath/>
    10. parent>
    11. <groupId>com.examplegroupId>
    12. <artifactId>redisData-demoartifactId>
    13. <version>0.0.1-SNAPSHOTversion>
    14. <name>redisData-demoname>
    15. <description>redisData-demodescription>
    16. <properties>
    17. <java.version>17java.version>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starter-data-redisartifactId>
    23. <version>3.0.4version>
    24. dependency>
    25. <dependency>
    26. <groupId>org.projectlombokgroupId>
    27. <artifactId>lombokartifactId>
    28. <version>1.18.26version>
    29. <optional>trueoptional>
    30. dependency>
    31. <dependency>
    32. <groupId>org.springframework.bootgroupId>
    33. <artifactId>spring-boot-starter-testartifactId>
    34. <version>3.1.0version>
    35. <scope>testscope>
    36. dependency>
    37. <dependency>
    38. <groupId>org.apache.commonsgroupId>
    39. <artifactId>commons-pool2artifactId>
    40. <version>2.11.1version>
    41. dependency>
    42. dependencies>
    43. <build>
    44. <plugins>
    45. <plugin>
    46. <groupId>org.springframework.bootgroupId>
    47. <artifactId>spring-boot-maven-pluginartifactId>
    48. <version>3.1.4version>
    49. <configuration>
    50. <excludes>
    51. <exclude>
    52. <groupId>org.projectlombokgroupId>
    53. <artifactId>lombokartifactId>
    54. exclude>
    55. excludes>
    56. configuration>
    57. plugin>
    58. plugins>
    59. build>
    60. project>

    在 application.properties 下 写入这些

    1. #这里是地址 localhost 对应 的 就是 127.0.0.1
    2. spring.data.redis.host=localhost
    3. #这里是端口号
    4. spring.data.redis.port=6379
    5. #如果你需要设置密码,就写这个 否则就不写
    6. #spring.data.redis.password=12345
    7. #当前使用的是哪一个 数据库 一共 是 下标 0 - 15
    8. spring.data.redis.database=1
    9. #是否使用线程池
    10. spring.data.redis.lettuce.pool.enabled=true
    11. #最大活动线程池个数
    12. spring.data.redis.lettuce.pool.max-active=8
    13. #最长等待时间 以毫秒 为单位
    14. spring.data.redis.lettuce.pool.max-wait=2000
    15. #这是最大 空闲 连接池 个数
    16. spring.data.redis.lettuce.pool.max-idle=8

    然后就是测试

    1. package com.example.redisdatademo;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. import org.springframework.data.redis.core.RedisTemplate;
    6. @SpringBootTest
    7. class RedisDataDemoApplicationTests {
    8. @Autowired
    9. private RedisTemplate redisTemplate;
    10. @Test
    11. void contextLoads() {
    12. }
    13. @Test
    14. void testString()
    15. {
    16. //写入一条 String 数据
    17. redisTemplate.opsForValue().set("user","lizeyan");
    18. String user = (String) redisTemplate.opsForValue().get("user");
    19. System.out.println("user : "+user);
    20. }
    21. }

    运行 testString  能正确输出即可

    SpringDataRedis  的 序列化方式

    RedisTemplate 可以 接收任意 Object 作为 值 写入Redis 只不过 写入前会把Object序列化 为字节形式  默认是采用JDK序列化的 ,得到的结构就会变成 这样

    缺点  可读性差,内存占用大

    我们可以重写方法 来修改 存入 redis 的数据状态

    1. package com.example.redisdatademo;
    2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
    3. import com.fasterxml.jackson.annotation.PropertyAccessor;
    4. import com.fasterxml.jackson.databind.ObjectMapper;
    5. import org.springframework.context.annotation.Bean;
    6. import org.springframework.context.annotation.Configuration;
    7. import org.springframework.data.redis.connection.RedisConnectionFactory;
    8. import org.springframework.data.redis.core.RedisTemplate;
    9. import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    10. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    11. import org.springframework.data.redis.serializer.RedisSerializer;
    12. import org.springframework.data.redis.serializer.StringRedisSerializer;
    13. import java.net.UnknownHostException;
    14. @Configuration
    15. public class redisDataConfig {
    16. @Bean
    17. public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
    18. {
    19. RedisTemplate redisTemplate = new RedisTemplate<>();
    20. redisTemplate.setConnectionFactory(redisConnectionFactory);
    21. // 设置key和hashKey的序列化器为String类型
    22. redisTemplate.setKeySerializer(new StringRedisSerializer());
    23. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    24. // 设置value和hashValue的序列化器为Jackson2JsonRedisSerializer
    25. Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
    26. ObjectMapper objectMapper = new ObjectMapper();
    27. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    28. objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    29. jsonRedisSerializer.setObjectMapper(objectMapper);
    30. redisTemplate.setValueSerializer(jsonRedisSerializer);
    31. redisTemplate.setHashValueSerializer(jsonRedisSerializer);
    32. redisTemplate.afterPropertiesSet();
    33. return redisTemplate;
    34. //
    35. // //创建 Template
    36. // RedisTemplate redisTemplate=new RedisTemplate<>();
    37. // //设置连接工厂
    38. // redisTemplate.setConnectionFactory(redisConnectionFactory);
    39. // //设置序列化工具
    40. // GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
    41. //
    42. // //key 和 hashKey 采用 string 序列化
    43. // redisTemplate.setKeySerializer(RedisSerializer.string());
    44. // redisTemplate.setHashKeySerializer(RedisSerializer.string());
    45. //
    46. // //value 和 hashValue 采用 string 序列化
    47. // redisTemplate.setValueSerializer(RedisSerializer.string());
    48. // redisTemplate.setHashValueSerializer(RedisSerializer.string());
    49. //
    50. // return redisTemplate;
    51. }
    52. }
    53. 要导入依赖

      1. <dependency>
      2. <groupId>com.fasterxml.jackson.coregroupId>
      3. <artifactId>jackson-databindartifactId>
      4. <version>2.15.1version>
      5. dependency>

      测试输出

      如果按照上面这个方式 那么会需要额外的存储空间来存储 这个类的路径  为了节省 内存空间  我们并不会 使用 JSON 序列化 来处理 value 而是 使用 String 序列化 器 。要求 只能存储 String 类型的 key 和 value ,当需要 存储 java 对象 时 手动 完成对象 的序列化 和 反序列化。

      Spring 默认提供了一个 StringRedisTemplate 类 它的 key 和 value 的序列化方式 默认就是String 方式 省去了 我们自定义 RedisTemplate 的过程

      1. package com.example.redisdatademo;
      2. import com.example.bean.User;
      3. import com.fasterxml.jackson.core.JsonProcessingException;
      4. import com.fasterxml.jackson.databind.ObjectMapper;
      5. import org.junit.jupiter.api.Test;
      6. import org.springframework.beans.factory.annotation.Autowired;
      7. import org.springframework.boot.test.context.SpringBootTest;
      8. import org.springframework.data.redis.core.RedisTemplate;
      9. import org.springframework.data.redis.core.StringRedisTemplate;
      10. @SpringBootTest
      11. class RedisDataDemoApplicationTests {
      12. @Autowired
      13. private RedisTemplate redisTemplate;
      14. @Autowired
      15. private StringRedisTemplate stringRedisTemplate;
      16. //JSON工具
      17. private static final ObjectMapper mapper=new ObjectMapper();
      18. @Test
      19. void contextLoads() {
      20. }
      21. @Test
      22. void testString()
      23. {
      24. //写入一条 String 数据
      25. redisTemplate.opsForValue().set("user","lizeyan");
      26. String user =(String) redisTemplate.opsForValue().get("user");
      27. System.out.println("user : "+user);
      28. }
      29. @Test
      30. void testObject()
      31. {
      32. redisTemplate.opsForValue().set("user:xm",new User("许墨",26));
      33. User newUser=(User) redisTemplate.opsForValue().get("user:xm");
      34. System.out.println(newUser);
      35. }
      36. @Test
      37. void testStringTemplate() throws JsonProcessingException {
      38. //准备对象
      39. User user=new User("helios",22);
      40. //手动序列化
      41. String json=mapper.writeValueAsString(user);
      42. //写入一条数据到 redis
      43. stringRedisTemplate.opsForValue().set("user:zql",json);
      44. //读取数据
      45. String val=stringRedisTemplate.opsForValue().get("user:zql");
      46. //反序列化
      47. User newUser=mapper.readValue(val,User.class);
      48. System.out.println("user : "+newUser);
      49. }
      50. }

      运行 testStringTemplate 就可以了 我们可以发现这个是没有类的路径的

       

    54. 相关阅读:
      几行cmd命令,轻松将java文件打包成jar文件
      Flink + Hudi 实现多流拼接(大宽表)
      什么是轮式里程计
      电子行业MES管理系统的主要功能与用途
      Python 框架学习 Django篇 (四) 数据库增删改查(CURD)
      易景地球网页版修改地球背景纹理方法
      数据库实验三——数据更新操作中经典题、难题以及易错题合集(含数据导入导出操作详细教程)
      【数据库】MySQL中的锁机制
      null 和 undefined 的区别
      Hyaluronic acid-siRNA透明质酸修饰核糖核酸|peptide–siRNA 多肽偶连RNA/DNA核酸(齐岳PNA修饰物)
    55. 原文地址:https://blog.csdn.net/lxh0113/article/details/133149343