一篇文章带你了解NoSql数据库——Redis简单入门
Redis是一个基于内存的key-value结构数据库
我们会利用其内存存储速度快,读写性能高的特点去完成企业中的一些热门数据的储存信息
在本篇文章中我们将会简单介绍Redis的入门,数据类型,常用命令以及如何在Java中操作Reids元素等内容
本篇内容属于《瑞吉外卖》的知识科普部分,有兴趣可以查看一下《瑞吉外卖》的相关文章内容
Redis入门
在下面我们将会介绍Redis的简介以及Redis的下载和相关配置
Redis简介
Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库,缓存和消息中间件。
Redis是用C语言开发的以恶搞开源的高性能键值对数据库,存储的value类型较为丰富,也被称为结构化的NoSql数据库
NoSql:全拼No Only SQL,不仅仅是SQL,泛指非关系型数据库。NoSql无法取代关系型数据库,而是作为关系型数据库的补充
我们常用的关系型数据库包括有:
Mysql
Oracle
DB2
SQLServer
我们常用的非关系型数据库包括有:
Redis
Mongo db
MemCached
我们的Redis常用于以下场景:
缓存
任务队列
消息队列
分布式锁
Redis下载与安装
我们将分为Window版下载安装和Linux版下载安装分开介绍:
Window版Redis
首先我们需要下载Redis压缩包,资料中有提供,我们也可以到官网下载:Redis中文网
Window版下载相对简单,我们只需要将压缩包解压到对应的文件夹下即可:
我们如果想要启动,只需点击redis-server.exe开启redis即可:
但是我们的实际操作通常是在redis-cli.exe里:
到这里Window版的Redis安装和启动就完成了
Linux版Redis
我们同样需要获得安装包,资料中有提供,当然也可以到官网下载:Redis中文网
Linux版的Redis下载就相对而言比较复杂:
将Redis安装包上传到Linux中
解压安装包
tar -zxvf redis-4.0.0.tar.gz -C /usr/local
安装Redis的依赖环境gcc
yum install gcc-c++
进入/usr/local/redis-4.0.0目录,进行编译
# 进入目录 cd /usr/local/redis-4.0.0 # 开启编译 make
进入redis的src目录,进行安装
# 进入src目录 cd src # 进行安装 make install
到这里我们的Linux安装就结束了
下面我们来介绍Linux的启动与停止:
使用redis-server启动,默认端口号为6379
# 进入目录 cd /usr/local/redis-4.0.0/src # 启动 ./redis-server
连接服务
# 这时我们的页面应该是Redis系统界面,我们需要重开一个页面进行Redis操作 # 我们通过cli连接服务 # 进入目录 cd /usr/local/redis-4.0.0/src # 连接服务 ./redis-cli # 查看数据 keys * # 可以使用Ctrl+C退出系统 Ctrl+C
关闭Redis服务器
# 查找Redis服务器进程号 ps -ef|grep redis # 关闭进程 kill -9 进程号
到这里Redis的启动与关闭就介绍完毕了
Redis相关配置
我们的Redis相关配置基本都是基于Linux系统进行配置的
后台服务
我们的Redis在启动时会占据整个屏幕,导致操作不便,所以我们需要将Redis设置为后台运行
# 进入配置文件 vim /usr/local/redis-4.0.0/redis.conf # 由于内容过多,我们通过查找/来查找相关信息 /daemonize # 我们将后面的no改为yes即可 # 注意:我们后面需要采用配置进行加载Redis,假设我们目前在/usr/local/redis-4.0.0目录下(如果已经开启,记得先关闭) src/redis-server ./redis.conf
图片展示:
设置密码
我们在登陆时会发现没有默认密码,这时我们的系统很容易被入侵,所以我们需要设置密码
# 进入配置文件 vim /usr/local/redis-4.0.0/redis.conf # 由于内容过多,我们通过查找/来查找相关信息 /pass # 将#号去掉,后面修改密码即可 requirepass 123456
然后我们登陆时就需要携带密码登录或者登陆后输入密码
# 登录 src/redis-server ./redis.conf -h localhost -p 6379 # 登录后输入密码(否则你的操作将会显示没有权限) auth 123456 # 登陆时携带密码 src/redis-server ./redis.conf -h localhost -p 6379 -a 123456
设置允许远程访问
在默认情况下我们是无法在外界连接,我们在Window界面的redis文件夹中使用PowerShell登陆界面(shift+右键):
所以我们需要进入虚拟机进行配置设置:
# 进入配置文件 vim /usr/local/redis-4.0.0/redis.conf # 由于内容过多,我们通过查找/来查找相关信息 /bind # 找到bind 127.0.0.1,将其注释掉即可 # 记得打开防火墙 firewall-cmd --zone=public -add-port=6379/tcp --permanent
图片展示:
之后我们再使用Window打开,就可以进行访问了:
Redis数据类型
Redis首先是一个键值对类型的数据库,保持key-value的形式
我们的key不用过多描述,一律为String类型保存,我们的value一共分为五种类型
我们给出视图展示:
我们简单介绍一下五种数据类型:
String字符串,储存普通元素
hash哈希表,存储对象
list列表,可以按照顺序排序,可以有重复元素
set无序集合,没有重复元素
sorted set有序集合,没有重复元素
Redis常用命令
我们将常用命令分为六类来进行讲解,下面仅介绍常用命令,如有需要可上官网查询:https://www.redis.net.cn/order/
字符串String操作命令
Redis中字符串类型常用命令有:
# 设置指定key的值 SET key value # 获得指定key的值 GET key # 设置指定key的值,并将key的过期时间设置为seconds秒 SETEX key seconds value # 只有在key不存在时设置key的值 SETNX key value
具体展示:
哈希Hash操作命令
Redis hash是一个String类型的field和value的映射表,hash特别适合用于存储对象,常用指令有:
# 将哈希表key中的字段field的值设为value HSET key field value # 获得存储在哈希表中的指定字段的值 HGET key field # 删除存储再哈希表中的指定字段 HDEL key field # 获得哈希表中所有字段 HKEYS key # 获得哈希表中所有值 HVALS key # 获得在哈希表中指定key的所有字段和值 HGETALL key
具体展示:
列表List操作命令
Redis List是相当于一个头插法的队列,按顺序排序,常用命令有:
# 将一个或多个值插入列表头部 LPUSH key value1 [value2] # 获得列表指定范围的元素 LRANGE key start stop # 移除并获得列表最后一个元素 RPOP key # 获得列表长度 LLEN key # 移除并获得列表最后一个元素,如果列表无元素则一直阻塞至等待超时或弹出元素为止 BRPOP key1 [key2] timeout
具体展示:
集合Set操作命令
Redis Set是String类型的无序集合,集合成员是唯一的,常用命令有:
# 向集合添加一个或多个成员 SADD key member1 [member2] # 返回集合中的所有成员 SMEMBERS key # 获得集合的成员数 SCARD key # 返回给定所有集合和交集 SINTER key1 [key2] # 返回给定所有集合和交集 SUNION key1 [key2] # 返回给定所有集合和交集 SDIFF key1 [key2] # 移除集合中一个或多个成员 SREM key member1 [member2]
具体展示:
有序集合SortedSet操作命令
Redis SortedSet是String类型的有序集合,根据其分数来从小到大排列,集合成员是唯一的,常用命令有:
# 向有序集合添加一个或多个成员或更新已存在成员的分数 ZADD key score1 member1 [score2 member2] # 通过索引区间返回有序集合中指定区间的成员 ZRANGE key start stop [WITHSCORES] # 有序集合中对指定成员的分数加上增量increment ZINCRBY key increment member # 移除有序集合的一个或多个成员 ZREM key member [member...]
具体展示:
通用命令
通用命令一般是针对key使用的命令,常用命令有:
# 查找所有符合给定模式的key(一般用*查找所有) KEYS pattern # 检查给定key是否存在 EXISTS key # 返回key所存储的值的类型 TYPE key # 返回给定key的剩余生命时间,以s为单位 TTL key # 删除指定的存在的key DEL key # 切换数据库(一共有16号数据库,默认使用0号数据库) select number
具体展示:
在Java中操作Redis
最后我们要来介绍Redis的实际使用,结合我们的Java来使用Redis
介绍
Redis的Java客户端有很多,官方推荐的主要是这三种:
Jedis
Lettuce
Redisson
其中Spring对Redis客户端进行了整合,提供了Spring Data Redis
在Spring Boot项目中还提供了对应的Starter,即Spring-boot-starter-data-redis
jedis
我们首先来学习Jedis的使用,Jedis使用在我们正常的Java项目中,它的地位就好似Mysql的JDBC一般
下面我们来了解其具体使用:
载入坐标
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>jedis_demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--用于测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--Jedis坐标--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> </dependencies> </project>
我们直接在测试类里书写代码
package com.itheima.test; import org.junit.Test; import redis.clients.jedis.Jedis; import java.util.Set; /** * 使用Jedis操作Redis * 我们大致分为三步:获得连接,执行具体操作,关闭连接 */ public class JedisTest { @Test public void testRedis(){ //1 获取连接(ip或者主机,端口号) Jedis jedis = new Jedis("localhost",6379); //2 执行具体的操作(指令基本和redis相同) jedis.set("username","xiaoming"); String value = jedis.get("username"); System.out.println(value); jedis.del("username"); jedis.hset("myhash","addr","bj"); String hValue = jedis.hget("myhash", "addr"); System.out.println(hValue); Set<String> keys = jedis.keys("*"); for (String key : keys) { System.out.println(key); } //3 关闭连接 jedis.close(); } }
Spring Data Redis
Spring为我们提供了Spring Data Redis,SDR使用在我们的SpringBoot项目中
Spring Data Redis提供了一个高度封装的类:RedisTemplate,针对jedis客户端中大量api进行了归类封装,将同一类操作进行封装
大致分为了以下五种分类:
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
下面我们来了解其具体使用:
载入坐标
<?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 http://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.4.5</version> <relativePath/> </parent> <groupId>com.itheima</groupId> <artifactId>springdataredis_demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <!--Spring Data Redis坐标--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.5</version> </plugin> </plugins> </build> </project>
yaml配置信息
spring: application: name: springdataredis_demo #Redis相关配置 redis: host: localhost port: 6379 #password: 123456 database: 0 #操作的是0号数据库 jedis: #Redis连接池配置 pool: max-active: 8 #最大连接数 max-wait: 1ms #连接池最大阻塞等待时间 max-idle: 4 #连接池中的最大空闲连接 min-idle: 0 #连接池中的最小空闲连接
配置Redis配置类解决序列化问题
package com.itheima.config; import org.springframework.cache.annotation.CachingConfigurerSupport; 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; /** * Redis配置类 */ @Configuration public class RedisConfig extends CachingConfigurerSupport { // 我们只需要对key进行序列化即可,我们在使用keys *查看key时可以直接查看 // 针对value,我们存入时会进行序列化,在我们采用方法读取时同样会进行反序列化,所以无需优化 @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); //默认的Key序列化器为:JdkSerializationRedisSerializer redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory(connectionFactory); return redisTemplate; } }
启动类书写
package com.itheima; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class,args); } }
我们采用测试的形式给出所有案例
package com.itheima.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.core.*; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @SpringBootTest @RunWith(SpringRunner.class) public class SpringDataRedisTest { // 我们在配置了yaml配置后,就可以自动装配RedisTemplate供我们使用 // 我们采用redisTemplate的方法来获得其他五类实体,也可以直接用redisTemplate调用通用命令 @Autowired private RedisTemplate redisTemplate; /** * 操作String类型数据 */ @Test public void testString(){ // redisTemplate.opsForValue()获得ValueOperations // SET redisTemplate.opsForValue().set("city123","beijing"); // GET String value = (String) redisTemplate.opsForValue().get("city123"); System.out.println(value); // 这里使用的是SETEX,注意时间是long型的 redisTemplate.opsForValue().set("key1","value1",10l, TimeUnit.SECONDS); // 这里使用的是SETNX Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city1234", "nanjing"); System.out.println(aBoolean); } /** * 操作Hash类型数据 */ @Test public void testHash(){ HashOperations hashOperations = redisTemplate.opsForHash(); //存值 HSET hashOperations.put("002","name","xiaoming"); hashOperations.put("002","age","20"); hashOperations.put("002","address","bj"); //取值 HGET String age = (String) hashOperations.get("002", "age"); System.out.println(age); //获得hash结构中的所有字段 HEKYS Set keys = hashOperations.keys("002"); for (Object key : keys) { System.out.println(key); } //获得hash结构中的所有值 HVALS List values = hashOperations.values("002"); for (Object value : values) { System.out.println(value); } } /** * 操作List类型的数据 */ @Test public void testList(){ ListOperations listOperations = redisTemplate.opsForList(); //存值 LPUSH listOperations.leftPush("mylist","a"); listOperations.leftPushAll("mylist","b","c","d"); //取值 RPOP List<String> mylist = listOperations.range("mylist", 0, -1); for (String value : mylist) { System.out.println(value); } //获得列表长度 llen Long size = listOperations.size("mylist"); int lSize = size.intValue(); for (int i = 0; i < lSize; i++) { //出队列 String element = (String) listOperations.rightPop("mylist"); System.out.println(element); } } /** * 操作Set类型的数据 */ @Test public void testSet(){ SetOperations setOperations = redisTemplate.opsForSet(); //存值 SADD setOperations.add("myset","a","b","c","a"); //取值 SMEMBERS Set<String> myset = setOperations.members("myset"); for (String o : myset) { System.out.println(o); } //删除成员 SREM setOperations.remove("myset","a","b"); //取值 SMEMBERS myset = setOperations.members("myset"); for (String o : myset) { System.out.println(o); } } /** * 操作ZSet类型的数据 */ @Test public void testZset(){ ZSetOperations zSetOperations = redisTemplate.opsForZSet(); //存值 ZADD zSetOperations.add("myZset","a",10.0); zSetOperations.add("myZset","b",11.0); zSetOperations.add("myZset","c",12.0); zSetOperations.add("myZset","a",13.0); //取值 ZRANGE Set<String> myZset = zSetOperations.range("myZset", 0, -1); for (String s : myZset) { System.out.println(s); } //修改分数 ZINCRBY zSetOperations.incrementScore("myZset","b",20.0); //取值 ZRANGE myZset = zSetOperations.range("myZset", 0, -1); for (String s : myZset) { System.out.println(s); } //删除成员 ZREM zSetOperations.remove("myZset","a","b"); //取值 ZRANGE myZset = zSetOperations.range("myZset", 0, -1); for (String s : myZset) { System.out.println(s); } } /** * 通用操作,针对不同的数据类型都可以操作 */ @Test public void testCommon(){ //获取Redis中所有的key KEYS * Set<String> keys = redisTemplate.keys("*"); for (String key : keys) { System.out.println(key); } //判断某个key是否存在 EXISTS Boolean itcast = redisTemplate.hasKey("itcast"); System.out.println(itcast); //删除指定key DEL redisTemplate.delete("myZset"); //获取指定key对应的value的数据类型 TYPE DataType dataType = redisTemplate.type("myset"); System.out.println(dataType.name()); } }
结束语
该篇内容到这里就结束了,希望能为你带来帮助~
附录
该文章属于学习内容,具体参考B站黑马程序员的Java项目实战《瑞吉外卖》
这里附上视频链接:Redis-01-Redis课程介绍_哔哩哔哩_bilibili
标签:
留言评论