当前位置: 首页> 汽车> 新车 > 手表网站排名186信息网_地方生活门户网站名称_seo整站优化技术培训_郑州百度seo排名公司

手表网站排名186信息网_地方生活门户网站名称_seo整站优化技术培训_郑州百度seo排名公司

时间:2025/7/8 16:23:14来源:https://blog.csdn.net/2301_80687933/article/details/144307494 浏览次数: 1次
手表网站排名186信息网_地方生活门户网站名称_seo整站优化技术培训_郑州百度seo排名公司

一、Redis 的数据结构

Redis是一个key-value的数据库,的key一般是String类型,不过value类型多种多样:

 二、通用命令

Redis为了方便我们学习,操作不同数据类型的命令也做了分组,在官网 https://redis.io/commands 可以查看到不同的命令: 

  • 查看通用的命令:

help @generic

查看单个命令的帮助,如 help keys

 

查看符合模板的key, 不建议在生产设备使用。因为redis是单线程的,在搜索符合的模板是会阻塞其他的命令,在集群中应避免在主节点使用该命令。

 

  • 批量插入key,value值

MSET key1 value1 …… key n value n 

 

  • 删除一个指定的key 

DEL key

 

  • 判断key是否存在,存在返回1,不存在返回0

EXISTS  key

  • 给一个key设置有效期(单位是秒),有效期到期时该key会被自动删除

EXPIRE  key  时间数

 

  • 查看一个KEY的剩余有效期

 TTL key

 

如果值为 -1 代表永久有效 

三 、String 类型

String类型,也就是字符串类型,是Redis中最简单的存储类型。其value是字符串,不过根据字符串的格式不同,又可以分为3类:

  1.  string:普通字符串
  2.  int:整数类型,可以做自增、自减操作
  3.  float:浮点类型,可以做自增、自减操作

 

String 类型常用命令

  • SET:添加或者修改已经存在的一个String类型的键值对

  • GET:根据key获取String类型的value

  • MSET:批量添加多个String类型的键值对

  • MGET:根据多个key获取多个String类型的value

  • INCR:让一个整型的key自增1

  • INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2

  • INCRBYFLOAT:让一个浮点类型的数字自增并指定步长

  • SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行

  • SETEX:添加一个String类型的键值对,并且指定有效期

插入key 为 teacher, value 为 zhangsan的键值对,10秒过后再次取值已经失效了。 

 

 扩展 

Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1

redis 的 key 允许多个单词用 : 隔开,格式可以是 项目名:业务名:类型:id。这个格式并非固定,可以按照实际需求。

 

四、Hash 类型

Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。

String 结构是将对象序列化为JSON后存储,需要修改某个字段时不方便。

Hash 结构可以将对象中的每个字段单独存储,可以对单个字段进行CRUD 

 常见命令

  • HSET key field value:添加或者修改hash类型keyfield的值

添加 

修改年龄

 

  • HGET key field:获取一个hash类型keyfield的值

  • HMSET:批量添加多个hash类型keyfield的值

添加一个key为 it:user:4 的 hash数据,插入了name = LiLei,age = 20 , sex = man 三个字段。

  • HMGET:获取指定key的多个字段值

获取key为 it:user:4 的 name、age 、sex字段。

  • HGETALL:获取指定key的所有字段和值

  • HKEYS:获取指定key的所有字段

  • HVALS:获取指定key的所有值

  • HINCRBY: 指定key的某个字段值自增并指定步长

  •  HSETNX:根据指定key值添加新字段,前提是这个field不存在,否则不执行

 

五、List类型

Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。

特征和LinkeList相似:有序、可重复、插入和删除快、查询效率一般

常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

List常见命令

  • LPUSH key  element ... :向列表左侧插入一个或多个元素,返回列表总个数

  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil

  • RPUSH key  element ... :向列表右侧插入一个或多个元素,返回列表总个数

  • RPOP key  [count]:移除并返回列表右侧的第一个元素

       可以跟取出的个数,如 rpop user 5,表示在key为user的列表中取出5个元素

  • LRANGE key star end:返回一段下标范围内的所有元素

如取出下标为 0 到 2 范围内列表的元素

  • BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间(单位 秒),而不是直接返回nil。

L 表示左边,R表示右边。 

思考:  

如何利用List结构模拟一个栈?

  •  入口和出口在同一边  

如何利用List结构模拟一个队列? 

  •  入口和出口在不同边 

如何利用List结构模拟一个阻塞队列?

  •  入口和出口在不同边
  •  出队时采用BLPOP或BRPOP

六、Set类型

  • Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:无序、不可重复、查找快、支持交集、并集
  • SADD key member ... :向set中添加一个或多个元素

        在队列s2中添加值 1,3,4,6 

  • SREM key member ... : 移除set中的指定元素

       移除队列名为s1的,且值为4的元素 

  • SCARD key: 返回set中元素的个数

  • SISMEMBER key member:判断一个元素是否存在于set中

        存在返回1, 不存在返回0 

  • SMEMBERS:获取set中的所有元素

  • SINTER key1 key2 ... :求key1与key2的交集

        显示s1 和 s2 的所有元素,并取 s1 和 s2 的交集 

  • SDIFF key1 key2 ... :求key1与key2的差集

  • SUNION key1 key2 ..:求key1和key2的并集

七、SortedSet类型

Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。 

  •  ZADD key score member:添加一个或多个元素到sorted set ,如果已经存在则更新其score

  • ZREM key member:删除sorted set中的一个指定元素

  • ZSCORE key member : 获取sorted set中的指定元素的score
  • ZRANK key member:获取sorted set 中的指定元素的排名

  • ZCARD key:获取sorted set中的元素个数
  • ZCOUNT key min max:统计score值在给定范围内的所有元素的个数

  • ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment
  • ZRANGE key min max:按照score排序后,获取指定排名范围内的元素

        升序获取前三名的元素 

       降序后获取前三名

      

  • ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
  • ZDIFFZINTERZUNION:求差集、交集、并集

注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可

八、Redis的JAVA客户端

1. Jedis 

 1.1 Jedis 使用步骤

  • 引入 Jedis 依赖
<dependency>    <groupId>redis.clients</groupId>    <artifactId>jedis</artifactId>    <version>3.7.0</version>
</dependency>
  • 注入模板,建立连接

/* 初始化 jedis */@BeforeEachvoid setUp() {// 建立连接jedis = new Jedis("192.168.30.130");// 设置密码jedis.auth("123456");// 选择库jedis.select(0);}
  • 使用 Jedis 操作数据
@Testvoid testString() {// 插入数据String result = jedis.set("name", "张三");System.out.println("result = " + result );// 获取数据String name = jedis.get("name");System.out.println("name = " + name);}
  • 释放连接
/* 释放资源 */@AfterEachvoid tearDown() {if (jedis != null) {jedis.close();}}

整体代码如下:

@SpringBootTest
class JedisDemoApplicationTests {private Jedis jedis;/* 初始化 jedis */@BeforeEachvoid setUp() {// 建立连接jedis = new Jedis("192.168.30.130");// 设置密码jedis.auth("123456");// 选择库jedis.select(0);}@Testvoid testString() {// 插入数据String result = jedis.set("name", "张三");System.out.println("result = " + result );// 获取数据String name = jedis.get("name");System.out.println("name = " + name);}/* 释放资源 */@AfterEachvoid tearDown() {if (jedis != null) {jedis.close();}}
}

1.2 Jedis 连接池

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

1. 创建一个名为JedisConnectPool的连接池工具类。

package com.example.jedis_demo.util;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** Jedis 连接池* */
public class JedisConnectPool {// 定义一个常量private static final JedisPool JEDIS_POOL;static {// 配置连接池JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();// 最大连接数量jedisPoolConfig.setMaxTotal(8);// 最大空闲连接数量jedisPoolConfig.setMaxIdle(8);// 最小空闲连接数量jedisPoolConfig.setMinIdle(0);// 创建连接, 1000ms 表示等待时间JEDIS_POOL = new JedisPool(jedisPoolConfig, "192.168.30.130", 6379, 1000, "123456");}// 获取 Jedis 对象public static Jedis getJedis() {return JEDIS_POOL.getResource();}}

2. 使用连接池

@SpringBootTest
class JedisDemoApplicationTests {private Jedis jedis;/* 初始化 jedis */@BeforeEachvoid setUp() {/*  // 建立连接jedis = new Jedis("192.168.30.130");// 设置密码jedis.auth("123456");*/jedis = JedisConnectPool.getJedis();// 选择库jedis.select(0);}@Testvoid testString() {// 插入数据String result = jedis.set("name", "张三");System.out.println("result = " + result );// 获取数据String name = jedis.get("name");System.out.println("name = " + name);}/* 释放资源 */@AfterEachvoid tearDown() {if (jedis != null) {jedis.close();}}
}

2. SpringDataRedis

现在多数的项目都是基于SpringBoot的,如何在SpringBoot中整合 Jedis 呢?

SpringData 是 Spring 中数据操作的模块,包含了各种数据库的集成,其中对redis数据库的继承模块叫做SpringDataRedis。官网地址:Spring Data Redis

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

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

 

 2.1 使用步骤

  • 引入spring-boot-starter-data-redis 依赖
  • 编写yml配置文件, 配置 Redis 
  • 注入 redisTemplate并使用

1. 引入依赖

 <!-- redis 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
<!-- 连接池依赖 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

2. 编写yml配置文件, 配置 Redis

spring:redis:port: 6379       # redis 端口host: 192.168.30.130  # 服务器IPpassword: 123456   # 密码jedis:pool:max-active: 8   # 最大连接数量max-idle: 8     # 最大空闲连接数min-idle: 0     #最小空闲连接数max-wait: 100    #等待连接时间

3. 注入 redisTemplate并使用

@SpringBootTest
class RedisTemplateDempApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {// 插入数据redisTemplate.opsForValue().set("name", "赵六");// 读取数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name = " + name);}}

 2.2 SpringDataRedis的序列化方式

RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果如下图所示,缺点是可读性差、占用内存大

可以使用自定义RedisTemplate 序列化方式。

1. 添加jackson依赖

  <!-- jackson 序列化--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>

2. 新建Redis配置类,设置key、value 的序列化方式。

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 1. 创建 redisTemplate 对象RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 2. 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 3. 设置序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 4. 设置key、hashKey 为String 序列化redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// 5. 设置 value、hashValue 为 Json 序列化redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashKeySerializer(jsonRedisSerializer);return redisTemplate;}
}

3. 测试。插入一条Object类型数据,查看是否序列化成功

创建一个实体对象

public class User {private String user;private Integer age;public User() {}public User(String user, Integer age) {this.user = user;this.age = age;}// 省略 get、set方法
}

引入Template 模板

@SpringBootTest
class RedisTemplateDempApplicationTests {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Testvoid testString() {// 插入数据redisTemplate.opsForValue().set("name", "赵六");// 读取数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name = " + name);}@Testvoid testSavaUser() {// 写入数据redisTemplate.opsForValue().set("user:1", new User("张无忌", 20));// 获取数据User u = (User) redisTemplate.opsForValue().get("user:1");System.out.println(u);}}

 2.3 手动序列化

尽管JSON的序列化方式可以满足我们的需求。但是Json 序列化器为了知道对象的类型,还会把实体类的类型添加上去,额外增加了内存开销。

为了节省内存空间,不采用Json序列化器处理value,而是通过采用String序列化器,但它只能存储String类型的key、value,如果需要存储Obect类型的value,需要手动序列化和反序列化。

 

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

 // JSON工具
private static final ObjectMapper mapper = new ObjectMapper();
// 序列化,序列化成json对象
String json = mapper.writeValueAsString(实体对象);
// 反序列化, 由json变成 实体对象
User user1 = mapper.readValue(val, User.class);

1. 引入序列化器依赖

   <!-- jackson 序列化--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>

2. 注入 StringRedisTemplate, 定义Json工具类

3. 定义实体对象,这里定义了一个 User 对象。

public class User {private String user;private Integer age;public User() {}public User(String user, Integer age) {this.user = user;this.age = age;}// 省略 get、set方法
}

4. 测试

@SpringBootTest
class RedisTemplateDempApplicationTests {@Autowiredprivate StringRedisTemplate StringredisTemplate;// JSON工具private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testStringTemplate() throws JsonProcessingException {User user = new User("张无忌1", 20);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据StringredisTemplate.opsForValue().set("user:2", json);// 获取数据String val = StringredisTemplate.opsForValue().get("user:2");// 反序列化User user1 = mapper.readValue(val, User.class);System.out.println(user1);}}

运行结果 

 

3 序列化两种方式总结

方案一:自定义序列化

1. 自定义RedisTemplate

2. 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二:手动序列化

1. 使用StringRedisTemplate

2. 写入Redis时,手动把对象序列化为JSON

3. 读取Redis时,手动把读取到的JSON反序列化为对象

 

关键字:手表网站排名186信息网_地方生活门户网站名称_seo整站优化技术培训_郑州百度seo排名公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: