第一章 Redis入门

Redis的常见命令和客户端使用

一、初识Redis

1、 认识NoSQL

NoSql可以翻译做Not Only Sql(不仅仅是SQL),或者是No Sql(非Sql的)数据库。是相对于传统关系型数据库而言,有很大差异的一种特殊的数据库,因此也称之为非关系型数据库

关系型数据库和非关系数据库的区别

扩展性

  • 关系型数据库集群模式一般是主从,主从数据一致,起到数据备份的作用,称为垂直扩展。
  • 非关系型数据库可以将数据拆分,存储在不同机器上,可以保存海量数据,解决内存大小有限的问题。称为水平扩展。
  • 关系型数据库因为表之间存在关联关系,如果做水平扩展会给数据查询带来很多麻烦

2、认识Redis

Redis诞生于2009年,全称是Remote Dictionary Server 远程词典服务器,是一个基于内存的键值型NoSQL数据库

特征

  • 键值(key-value)型,value支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
  • 支持数据持久化
  • 支持主从集群、分片集群
  • 支持多语言客户端

3、安装Redis

https://blog.csdn.net/hc1285653662/article/details/127819045

二、Redis常见命令

1、Redis通用命令

通用指令是部分数据类型的,都可以使用的指令,常见的有:

  • KEYS:查看符合模板的所有key,不建议在生产环境下使用
  • DEL:删除一个指定的key,返回值是删除成功的数量
  • EXISTS:判断key是否存在
  • EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
  • TTL:查看一个KEY的剩余有效期

通过help [command] 可以查看一个命令的具体用法,例如:

# 查看keys命令的帮助信息:
127.0.0.1:6379> help keysKEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic

2、String类型

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

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

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m

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

2)Key结构
Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?
例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1,此时如果使用id作为key,那就会冲突了,该怎么办?
我们可以通过给key添加前缀加以区分,不过这个前缀不是随便加的,有一定的规范:
Redis的key允许有多个单词形成层级结构,多个单词之间用’:'隔开,格式如下:

项目名:业务名:类型:id

例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:

  • user相关的key:heima:user:1

  • product相关的key:heima:product:1

如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:

KEY VALUE
heima:user:1 {“id”:1, “name”: “Jack”, “age”: 21}
heima:product:1 {“id”:1, “name”: “小米11”, “price”: 4999}

并且,在Redis的桌面客户端中,还会以相同前缀作为层级结构,让数据看起来层次分明,关系清晰:

3、Hash类型

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

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


Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:

Hash的常见命令有:

  • HSET key field value:添加或者修改hash类型key的field的值
  • HGET key field:获取一个hash类型key的field的值
  • HMSET:批量添加多个hash类型key的field的值
  • HMGET:批量获取多个hash类型key的field的值
  • HGETALL:获取一个hash类型的key中的所有的field和value
  • HKEYS:获取一个hash类型的key中的所有的field
  • HVALS:获取一个hash类型的key中的所有的value
  • HINCRBY:让一个hash类型key的字段值自增并指定步长
  • HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

4、List类型

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

特征也与LinkedList类似:

  • 有序
  • 元素可以重复
  • 插入和删除快
  • 查询速度一般

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

List的常见命令有:

  • LPUSH key element … :向列表左侧插入一个或多个元素
  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
  • RPUSH key element … :向列表右侧插入一个或多个元素
  • RPOP key:移除并返回列表右侧的第一个元素
  • LRANGE key star end:返回一段角标范围内的所有元素
  • BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

5、Set 类型

Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:

  • 无序
  • 元素不可重复
  • 查找快
  • 支持交集、并集、差集等功能

Set的常见命令有:

  • SADD key member … :向set中添加一个或多个元素
  • SREM key member … : 移除set中的指定元素
  • SCARD key: 返回set中元素的个数
  • SISMEMBER key member:判断一个元素是否存在于set中
  • SMEMBERS:获取set中的所有元素
  • SINTER key1 key2 … :求key1与key2的交集
  • SDIFF key1 key2 : 求key1与key2的差集,就是key1有的,key2没的
  • SUNION key1 key2 : 求key1与key2的并集

例如两个集合:s1和s2:
求交集:SINTER s1 s2
求s1与s2的不同:SDIFF s1 s2

6、SortedSet类型

SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。

SortedSet具备下列特性:

  • 可排序
  • 元素不重复
  • 查询速度快
    因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

SortedSet的常见命令有:

  • 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范围内的元素
  • ZDIFF、ZINTER、ZUNION:求差集、交集、并集

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

  • 升序获取sorted set 中的指定元素的排名:ZRANK key member
  • 降序获取sorted set 中的指定元素的排名:ZREVRANK key memeber

三、Redis客户端

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/docs/clients/

其中Java客户端也包含很多:

标记为*的就是推荐使用的java客户端,包括:

  • Jedis和Lettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringDataRedis来学习。
  • Redisson:是在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map、Queue等,而且支持跨进程的同步机制:Lock、Semaphore等待,比较适合用来实现特殊的功能需求。

1、Jedis快速入门

1)引入依赖:

<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency>
<!--单元测试-->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>test</scope>
</dependency>

2)建立连接

新建一个单元测试类,内容如下:

private Jedis jedis;@BeforeEach
void setUp() {// 1.建立连接// jedis = new Jedis("192.168.150.101", 6379);jedis = JedisConnectionFactory.getJedis();// 2.设置密码jedis.auth("123321");// 3.选择库jedis.select(0);
}

3)测试:

@Test
void testString() {// 存入数据String result = jedis.set("name", "虎哥");System.out.println("result = " + result);// 获取数据String name = jedis.get("name");System.out.println("name = " + name);
}@Test
void testHash() {// 插入hash数据jedis.hset("user:1", "name", "Jack");jedis.hset("user:1", "age", "21");// 获取Map<String, String> map = jedis.hgetAll("user:1");System.out.println(map);
}

4)释放资源

@AfterEach
void tearDown() {if (jedis != null) {jedis.close();}
}
  1. 连接池

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

package com.heima.jedis.util;import redis.clients.jedis.*;public class JedisConnectionFactory {private static JedisPool jedisPool;static {// 配置连接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(8);poolConfig.setMaxIdle(8 poolConfig.setMinIdle(0);poolConfig.setMaxWaitMillis(1000);// 创建连接池对象,参数:连接池配置、服务端ip、服务端端口、超时时间、密码jedisPool = new JedisPool(poolConfig, "192.168.150.101", 6379, 1000, "123321");}public static Jedis getJedis(){return jedisPool.getResource();}
}

2、SpringDataRedis客户端

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

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

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

1)、快速入门

1)引入依赖

<?xml version="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.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.heima</groupId><artifactId>redis-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>redis-demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!--redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--common-pool 兼容jedis和lu--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!--Jackson依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

2)配置Redis

spring:redis:host: 192.168.150.101port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms

3)注入RedisTemplate

因为有了SpringBoot的自动装配,我们可以拿来就用:

@SpringBootTest
class RedisStringTests {@Autowiredprivate RedisTemplate redisTemplate;
}

4)编写测试

@SpringBootTest
class RedisStringTests {@Autowiredprivate RedisTemplate edisTemplate;@Testvoid testString() {// 写入一条String数据redisTemplate.opsForValue().set("name", "虎哥");// 获取string数据Object name = stringRedisTemplate.opsForValue().get("name");System.out.println("name = " + name);}
}

2) 自定义序列化

RedisTemplate可以接收任意Object作为值写入Redis:

只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:

缺点:

  • 可读性差
  • 内存占用较大

我们可以自定义RedisTemplate的序列化方式,代码如下:

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){// 创建RedisTemplate对象RedisTemplate<String, Object> template = new RedisTemplate<>();// 设置连接工厂template.setConnectionFactory(connectionFactory);// 创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 设置Key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 设置Value的序列化template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 返回return template;}
}

这里采用了JSON序列化来代替默认的JDK序列化方式。最终结果如图:

整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。

3)StringRedisTemplate

为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

省去了我们自定义RedisTemplate的序列化方式的步骤,而是直接使用:

@Autowired
private StringRedisTemplate stringRedisTemplate;
// JSON序列化工具
private static final ObjectMapper mapper = new ObjectMapper();@Test
void testSaveUser() throws JsonProcessingException {// 创建对象User user = new User("虎哥", 21);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:200", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user:200");// 手动反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println("user1 = " + user1);
}

Redis入门到实战(一、基础篇)【黑马程序员】相关推荐

  1. k8s之Pod详解(五)【Kubernetes(K8S) 入门进阶实战完整教程,黑马程序员K8S全套教程(基础+高级)】

    参考于Kubernetes(K8S) 入门进阶实战完整教程,黑马程序员K8S全套教程(基础+高级) Pod Pod的结构 每个Pod中都可以包含一个或者多个容器 这些容器可以分为两类: 用户自定义用的 ...

  2. 【CSS基础】黑马程序员web前端开发入门(三)视频笔记

    标题 1 基础认知 1.1 体验CSS 1.1.1 CSS的介绍 1.1.2 CSS语法规则 1.2 CSS引入方式 2 基础选择器 2.1 标签选择器 2.2 类选择器 2.3 id选择器 2.4 ...

  3. Python网络爬虫与信息提取(9)—— scrapy实战之爬取黑马程序员网页讲师信息

    前言 之前是使用request库爬取网页,但是大型的网络爬虫使用框架爬取会事半功倍,今天实战爬取这个网页讲师的信息:https://www.itcast.cn/channel/teacher.shtm ...

  4. 零基础JAVA——黑马程序员课程笔记

    视频地址:点击访问 (我这里开发工具有时候用eclipse有时候用IDEA,看每个人的习惯) (文中代码部分不会和老师讲的一模一样,因为我都是在看到老师给的案例后自己尝试写的,推荐大家这样做,可以帮助 ...

  5. 0基础跟着黑马程序员学微信小程序前端开发Day01

    学习目录 一.项目的基本组成结构 二.小程序页面的组成部分 三.创建小程序页面 四.小程序的一些组件 1.常用视图容器类组件 2.常用基础内容组件 3.button 按钮的基本使用 4.image 组 ...

  6. Git基础学习(黑马程序员笔记)

    Git介绍 Git是目前世界上最先进的分布式版本控制系统 Git安装 官网 Git与Github 两者区别 Git是一个分布式版本库控制系统,简单的说就是一个软件,用于记录一个或若干文件内容变化,以便 ...

  7. 机器学习入门笔记 人工智能 黑马程序员

    机器学习入门笔记 前言 这个是根据"黑马程序员"的一套机器学习课程编写的博客.这篇博客上的案例均为课程里面的,但并没有包含所有案例,只是记录了部分. B站视频地址 文章目录 机器学 ...

  8. python设计游戏的背景_04_游戏背景 — 黑马程序员《Python入门教程完整版》笔记...

    游戏背景 黑马程序员<Python入门教程完整版>笔记 - 黑马程序员<Python入门教程完整版>笔记 目标背景交替滚动的思路确定 显示游戏背景 01. 背景交替滚动的思路确 ...

  9. Redis入门到实战(实战篇)缓存更新、穿透、雪崩、击穿!

    Redis基础篇 Java面试宝典-redis 实战篇Redis 开篇导读 亲爱的小伙伴们大家好,马上咱们就开始实战篇的内容了,相信通过本章的学习,小伙伴们就能理解各种redis的使用啦,接下来咱们来 ...

  10. SpringBoot系统整理|基础篇|黑马视频

    写在前面:很早之前看了狂神的springboot快速入门,后来发现还是有很多开发知识点需要补充学习.乘着假期,将基础篇.运维实用篇.开发实用篇.原理篇一口气学习巩固,再次记录下学习笔记.系列笔记在sp ...

最新文章

  1. mysqldump工具,工作的本质是什么呢?(dump表的时候,是否会产生drop表的语句)
  2. 因特尔显卡自定义分辨率_iGame RTX 30系显卡《赛博朋克2077》测试
  3. 线程的四种实现方式,一些方法及线程的同步
  4. 18 网络编程-TCP/IP各层介绍(5层模型讲解)
  5. Android 手机重启相关内容
  6. Analysis of Struts2 : http://wenku.baidu.com/view/ad421874a417866fb84a8e75.html
  7. 解决方案和项目的区别_(实习招聘)PwC面试官问Advisory和Consulting有什么区别,怎么答?...
  8. 长沙周边最美露营基地:安化云台山风景区星空露营公园
  9. mysql的基本情况是什么意思_数据库是什么意思
  10. Leetcode刷题100天—49. 字母异位词分组( 排序)—day37
  11. 官方2013年6月CISA考试报名时间公布
  12. 慰问敬老院活动方案3
  13. 使用IIS网址重写来阻止图像热链接,渗漏和邪恶Splogger
  14. 苹果字体怎么改_LED显示屏屏幕上的文字怎么改?
  15. 14- webpack 压缩 html 代码
  16. 基于Python-opencv的车牌识别系统
  17. 怎么录制电脑上的屏幕视频?好用教程分享给你
  18. 注册表计算机性能设置怎么应用,巧用Windows注册表保障自己系统安全
  19. Centos7安装mysql-5.7.18-1.el7.x86_64.rpm-bundle.tar
  20. 中国航空机场行业“十四五”规划及项目投资建议报告2021-2027年

热门文章

  1. Zemax光学设计(七)——牛顿望远镜
  2. 用计算机控制人造卫星属于,2012年7月全国高校计算机联合考试(广西考区)一级笔试试题及答案...
  3. 微信小程序加入微信支付功能
  4. 防火墙和iptables
  5. matlab水果定位与分割,利用Matlab软件和BP神经网络快速识别水果实现分拣
  6. 入职三天,公司给了100块钱叫我走人| 掘金技术征文
  7. 解决电脑部分软件显示网络连接异常,或者界面加载不成功问题
  8. html5 canvas文本,html5 canvas文本处理
  9. pert计算公式期望值_PERT和CPM的最大区别在于PERT()。A.在计算进度计划时使用分布均值(期望值)B.使用最可能的估算...
  10. 统计网络学堂上提交的作业和论文2022