上篇文章:
Redis数据类型之zsethttps://blog.csdn.net/sniper_fandc/article/details/149139955?fromshare=blogdetail&sharetype=blogdetail&sharerId=149139955&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link
目录
1 Redis客户端和服务器使用自定义协议
2 Java集成Redis
2.1 端口开放
2.2 依赖引入
2.3 测试连接
2.4 set和get测试
2.5 exists和del测试
2.6 keys测试
2.7 expire和ttl测试
2.8 type测试
3 SpringBoot集成Redis
3.1 配置文件
3.2 使用方法
3.2.1 引入依赖
3.2.2 注入Bean
3.2.3 使用redis
1 Redis客户端和服务器使用自定义协议
Redis客户端和服务器使用自定义协议(应用层)进行网络通信,即RESP协议。
RESP协议是基于序列化的协议,传输的数据以字符串格式组织。优点是:1.简单好实现。2.快速进行解析。3.肉眼可读。
该协议的传输层协议是TCP,但是只使用了TCP协议的连接操作,其他的没再使用。请求和响应之间采用:一问一答的形式。请求发送客户端的Redis命令的bulk strings数组,响应返回的类型不同,根据不同Redis命令的实现返回不同类型的响应(OK、整数、数组等等)。
对于请求和响应的数据的字符串有5种类型:
(1)Simple Strings:以+开头的字符串,只能传输简单的文本,不能传输二进制安全的数据。
(2)Errors:以-开头的字符串。
(3)Integers:以:开头的字符串。
(4)Bulk Strings:以$开头的字符串,能传输二进制安全的数据。
(5)Arrays:以*开头的字符串。
2 Java集成Redis
2.1 端口开放
使用Java访问Redis如果采用本地方式访问,即Java程序和Redis服务器在一台主机上,通过127.0.0.1:6379即可访问。但是Java客户端如果想要跨主机访问Redis客户端,就必须通过公网IP来访问,这就会把Redis的端口6379暴露在公网中,很容易遭受黑客入侵。
解决办法是使用ssh协议,配置ssh端口转发,把远程Redis服务器的端口号映射到本地主机。ssh协议通常用于Windows与Linux系统网络交互,默认端口号22,由于ssh协议是加密的网络传输协议,安全程度很高,因此可以构造ssh请求包,把希望访问Redis端口号6379构造成ssh请求包的数据,通过22端口传输到Linux服务器,再由Linux服务器的ssh协议解析请求。
由于可能有多个客户端想要跨主机访问Linux服务器的其他服务器的端口号,ssh为了区分这些端口号,就会把Linux的各种服务的端口号映射到本地主机(发出访问请求的主机)的其他端口号(比如Linux的Redis端口6379映射到本地主机8888端口),从而达到客户端访问本地端口即可实现访问Redis端口,这就是ssh的端口转发功能。客户端访问本地端口,其余的事情都有ssh来完成(数据通过ssh协议的加密通道完成传输)。
这里使用FinalShell终端连接工具,其他终端连接工具都有类似的界面:
选择新建隧道,配置ip和端口号,这里类型是本地,没有用到跨主机连接(远程类型)。目标地址是Redis服务器的地址,即Linux的地址。监听端口表示Redis端口映射到本地的端口是8888:
8888端口出现监听状态,说明配置成功。
2.2 依赖引入
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.2</version></dependency>
2.3 测试连接
public void testRedis(){JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = jedisPool.getResource()){String pong = jedis.ping();System.out.println("收到来自Redis服务器的响应:" + pong);}}
由于配置了ssh端口转发,因此这里访问本机的8888端口即可访问Redis的服务器。
2.4 set和get测试
public void testSetAndGet(){try(Jedis jedis = jedisPool.getResource()){SetParams setParams = new SetParams();setParams.px(10);jedis.set("javatest","1");String result = jedis.get("javatest");System.out.println("javatest:" + result);}}
2.5 exists和del测试
public void existanddel(){try(Jedis jedis = jedisPool.getResource()){jedis.set("javatest","1");Boolean result = jedis.exists("javatest");System.out.println("javatest是否存在?" + result);Long delResult = jedis.del("javatest","javatest2");System.out.println("删除元素个数:" + delResult);result = jedis.exists("javatest");System.out.println("javatest是否存在?" + result);}}
2.6 keys测试
public void keys(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("javatest","1");jedis.set("javatest2","2");Set<String> result = jedis.keys("*");System.out.println(result.toString());}}
2.7 expire和ttl测试
public void expireAndTtl(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("javatest","1");jedis.expire("javatest",10);System.out.println("等待3s后");Thread.sleep(3000);Long time = jedis.ttl("javatest");System.out.println("剩余的时间:" + time + "s");} catch (InterruptedException e) {throw new RuntimeException(e);}}
2.8 type测试
public void type(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("key1","1");String result1 = jedis.type("key1");System.out.println("key1类型为:" + result1);jedis.lpush("key2","1","2");String result2 = jedis.type("key2");System.out.println("key2类型为:" + result2);jedis.hset("key3","field1","1");String result3 = jedis.type("key3");System.out.println("key3类型为:" + result3);jedis.sadd("key4","1","2");String result4 = jedis.type("key4");System.out.println("key4类型为:" + result4);jedis.zadd("key5",10,"user1");String result5 = jedis.type("key5");System.out.println("key5类型为:" + result5);}}
其余的命令不再演示,Jedis提供的Java客户端访问Redis的命令基本和Redis客户端的命令一致,使用很简单,只是需要注意返回值和变长参数(或者是Map来组织变长参数)。
3 SpringBoot集成Redis
3.1 配置文件
# Redis配置spring:redis:host: 127.0.0.1port: 8888
3.2 使用方法
3.2.1 引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
该依赖是SpringBoot集成的Redis依赖Spring Data Redis,SpringBoot 2内置的Redis是Lettuce实现,而不是Jedis实现,因此使用上有点区别。
3.2.2 注入Bean
@Autowiredprivate StringRedisTemplate redisTemplate;
这里StringRedisTemplate是已经交付给Spring管理的Bean,它是RedisTemplate的子类。RedisTemplate通过泛型控制是处理文本类型的数据还是处理字节类型的数据。
3.2.3 使用redis
@RequestMapping("/springbootRedis")@RestControllerpublic class RedisController {@Autowiredprivate StringRedisTemplate redisTemplate;@RequestMapping("/test")public void useRedis(){// 使用opsForXXX()方法得到对应类型的操作对象// string类型的操作redisTemplate.opsForValue().set("key","1");String result = redisTemplate.opsForValue().get("key");System.out.println("key:" + result);redisTemplate.delete("key");// list类型的操作redisTemplate.opsForList().leftPush("key", "a");redisTemplate.opsForList().leftPushAll("key", "b", "c", "d");List<String> values = redisTemplate.opsForList().range("key", 1, 2);System.out.println(values);redisTemplate.delete("key");// hash类型的操作redisTemplate.opsForHash().put("key", "name", "zhangsan");String value = (String) redisTemplate.opsForHash().get("key", "name");System.out.println(value);redisTemplate.opsForHash().delete("key", "name");boolean ok = redisTemplate.opsForHash().hasKey("key", "name");System.out.println(ok);redisTemplate.delete("key");// set类型的操作redisTemplate.opsForSet().add("key", "aaa", "bbb", "ccc");boolean ok1 = redisTemplate.opsForSet().isMember("key", "aaa");System.out.println(ok1);redisTemplate.opsForSet().remove("key", "aaa");long n = redisTemplate.opsForSet().size("key");System.out.println(n);redisTemplate.delete("key");// zset类型的操作redisTemplate.opsForZSet().add("key", "user1", 100);redisTemplate.opsForZSet().add("key", "user2", 98);redisTemplate.opsForZSet().add("key", "user3", 95);Set<String> values2 = redisTemplate.opsForZSet().range("key", 0, 2);System.out.println(values2);long n2 = redisTemplate.opsForZSet().count("key", 95, 100);System.out.println(n);redisTemplate.delete("key");}}
这里的使用方法是先要用opsForXXX()方法获取不同类型的操作对象,再通过该操作对象来进行操作。具体的api可能和命令不一样,但是通过方法的名字也可以知道该方法对应的命令。
下篇文章:
Redis原理之持久化https://blog.csdn.net/sniper_fandc/article/details/149140995?fromshare=blogdetail&sharetype=blogdetail&sharerId=149140995&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link