第十章:如何真正使用Java操作redis
一. Redis客户端
1.1Redis 命令与客户端程序
前面学习的 Redis 基本操作和命令都是在 Redis 命令行客户端手动执行的,这种方式并非日常开发的主要形式。在实际开发中,更多的是使用 Redis 的 API 来实现定制化的 Redis 客户端程序,从而操作 Redis 服务器。
Redis 提供的命令行客户端以及第三方的图形化客户端本质上都属于 “通用的客户端程序”,而在工作中更希望使用的是 “专用的”“定制化” 的客户端程序。
需要明确的是,前面学习的 Redis 命令是有价值的,因为 Redis 命令相当于使用代码来执行操作。
1.2自定义 Redis 客户端的可行性
我们能够编写自定义的 Redis 客户端,这是因为 Redis 公开了其自定义的应用层协议。而像 QQ、《王者荣耀》等软件,由于没有公开它们使用的自定义协议,所以一般情况下我们不能编写它们的自定义客户端(虽然网上有一些开源项目通过抓包、逆向等手段实现了自定义 QQ 客户端,但这属于逆向工程范畴,过程具有不确定性)。
1.3Redis 应用层协议(RESP)
- 协议层次:在网络通信中,有应用层、传输层(TCP/UDP 协议)、网络层(IP 协议)、数据链路层(以太网)和物理层。其中传输层、网络层等协议是固定的,在系统内核或驱动程序中实现,程序只能选择不能修改。而应用层协议可以自定义,Redis 自定义的应用层协议就是 RESP(Redis Serialization Protocol)。
- RESP 协议的作用:客户端按照应用层协议发送请求,服务器按照协议进行解析,再构造响应,客户端再解析响应。这种通信能够完成是因为开发客户端和服务器的人都清楚协议的细节。
- RESP 协议的优点:简单好实现、快速进行解析、肉眼可读。
- 通信模型:请求和响应之间是一问一答的形式,基于 TCP 传输但又和 TCP 没有强耦合。
- 数据类型与格式:在 RESP 中,第一个字节决定了数据类型,例如:
- 简单字符串(Simple Strings):回复的第一个字节是 “+”,只能用来传输文本。
- 错误(Errors):回复的第一个字节是 “-”。
- 整数(Integers):回复的第一个字节是 “:”。
- 批量字符串(Bulk Strings):回复的第一个字节是 “$”,可以传输二进制数据。
- 数组(Arrays):回复的第一个字节是 “*”。
- 实际应用:在实际编写代码时,不需要手动按照上述协议解析和构造字符串,因为已经有很多开发者提供了实现这套协议解析和构造的库,使用这些库可以简单方便地完成与 Redis 服务器的通信操作。
1.3为什么不能直接打开redis的6379端口?
1.了解开发redis的风险
- 开发环境与访问需求
在 Java 开发中,开发者高度依赖 Windows 系统(如 IDEA 等开发工具)。当需要访问部署在 Linux 云服务器上的 Redis 服务器时,需借助云服务器的外网 IP 来建立连接,实现从本地 Windows 电脑(Redis 客户端)到远程服务器的访问。 - 云服务器端口保护机制
仅修改为外网 IP 并不能解决访问问题。Redis 默认的 6379 端口会被云服务器的防火墙保护,导致外部设备无法访问该端口。防火墙在阻止黑客入侵的同时,也阻碍了开发者自身的正常访问,形成了一道安全与访问之间的屏障。 - 网络安全与端口开放的权衡
个人 Windows 电脑如同小区里的住宅楼,受 NAT 机制保护,外人入侵成本高;而云服务器有外网 IP,相当于暴露在大街上的门市房,相对更容易被攻击。每给云服务器开放一个端口,就如同多开了一扇门,增加了被入侵的风险。 - Redis 端口直接开放的风险
直接在云服务器后台放开防火墙来解决访问问题不可取。Redis 的端口一旦公开到公网上,极易被入侵。尽管像 Tomcat 的 8080 端口也开放,但 Redis 的 6379 端口安全性较低,若开放,不出 3 天服务器就可能被黑客入侵,已有诸多案例证实这一点.认为给 Redis 换个端口(如 7379)就能提高安全性是错误的,这只是掩耳盗铃,无法从根本上阻止黑客的入侵行为。
2.配置 ssh 端口转发
可以通过配置 ssh 端口转发,将云服务器的 Redis 端口映射到本地主机。此时,客户端程序访问本地的 127.0.0.1:8888,就相当于访问 Linux 服务器的 6379 端口。
- 相关设备与端口
Windows 主机上有多个端口,如 8888(ssh 程序监听的端口)、8889、8890 等。Linux 服务器上除了 Redis 所在的 6379 端口,还有 6380、6381 等其他端口。我们可以通过终端(如 xshell)远程登录到 Linux 服务器。 - ssh 协议的作用
ssh 协议默认通过 22 端口进行通信,它功能强大,其中一个重要特性是支持端口转发,能够借助 22 端口来传递其他端口的数据。 - 数据传输过程
当需要从 Windows 主机访问云服务器的 6379 端口时,会构造一个特殊的 ssh 数据报,将访问 Redis 的请求包含在其中。这个数据报通过 22 端口发送给服务器,服务器的 ssh 服务器程序解析出数据报后,会将其交给 6379 端口的程序进行处理。 - 端口区分与使用
在 Linux 主机上可能存在多个服务器,ssh 可能需要为多个端口传递数据。为了区分不同的端口,通常会在本地用另外一个端口来表示服务器的端口。只要进行简单配置,后续就可以将云服务器的端口当作本地端口来使用,这就是 ssh 端口转发、映射或隧道技术。 - Redis 服务器配置要点
要使程序能够正常运行,除了配置 ssh 端口映射外,在最初安装 Redis 服务器时,还需要注意两个关键配置:- 绑定 IP:默认绑定的 IP 是 127.0.0.1,这意味着只能在本机访问,无法跨主机访问。需要将其配置为 bind 0.0.0.0 以支持跨主机访问。
- 保护模式:默认情况下保护模式为 yes,开启后跨主机也无法访问。需要将其设置为 protected-mode no 来关闭保护模式,允许跨主机访问。
1.4Java连接客户端步骤
1.映射端口
2.cmd查看是否连接成功
二.Java使用Jedis编写常用命令
下面只是简单介绍基础命令,其他没用到可以去gitHub-redis-jedis寻找
1.打开Maven-搜索Jedis
2.复制坐标依赖-去放到pom文件
2.1redisDemo
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class redisDemo {public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){String res = jedis.ping();System.out.println(res);}}
}
2.2set和get
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class redisDemo {public static void testSetAndGet(Jedis jedis){System.out.println("get 和 set 的使用");jedis.flushAll();//先清空库(慎用!)jedis.set("key1", "111");String value = jedis.get("key1");System.out.println("value = " + value);}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){redisDemo.testSetAndGet(jedis);}}
}
参数:ex,nx
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;public class redisDemo {public static void testSetAndGet(Jedis jedis){System.out.println("get 和 set 的使用");jedis.flushAll();//先清空库(慎用!)jedis.set("key1", "111");String value = jedis.get("key1");System.out.println("value = " + value);System.out.println("***********************************");
//******************************************************SetParams params = new SetParams();params.ex(10);//设置过期时间为10秒params.nx(); //只在key不存在时,才执行set操作jedis.set("key2","222",params);String value1 = jedis.get("key2");System.out.println("value1 = " + value1);}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){redisDemo.testSetAndGet(jedis);}}
}
参数:ex,xx
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;public class redisDemo {public static void testSetAndGet(Jedis jedis){System.out.println("get 和 set 的使用");jedis.flushAll();//先清空库(慎用!)jedis.set("key1", "111");String value = jedis.get("key1");System.out.println("value = " + value);System.out.println("***********************************");
//******************************************************SetParams params = new SetParams();params.ex(10);//设置过期时间为10秒params.nx(); //只在key不存在时,才执行set操作jedis.set("key2","222",params);String value1 = jedis.get("key2");System.out.println("value1 = " + value1);//******************************************************System.out.println("***********************************");SetParams params1 = new SetParams();params1.ex(100);//设置过期时间为100秒params1.xx(); //只在key存在时,才执行set操作jedis.set("key3","333");String value3 = jedis.get("key3");System.out.println("value3 = "+value3);jedis.set("key3","3333333",params1);String value4 = jedis.get("key3");System.out.println("value3 = "+value4);jedis.set("key4","444",params1);String value5 = jedis.get("key4");System.out.println("value5 = "+value5);System.out.println("***********************************");}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){redisDemo.testSetAndGet(jedis);}}
}
2.3del和exists
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;public class redisDemo {public static void delAndExixts(Jedis jedis){jedis.flushAll();//先清空库(慎用!)jedis.set("key1","111");String value1 =jedis.get("key1");System.out.println("value1 = "+value1);jedis.exists("查看key1是否存在"+"key1");long del = jedis.del("key1");System.out.println("查看是否删除del : "+del);System.out.println("查看是否存在key1 : "+jedis.exists("key1"));}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){//redisDemo.testSetAndGet(jedis);redisDemo.delAndExixts(jedis);}}
}
2.4keys
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public class redisDemo {public static void keys(Jedis jedis){jedis.flushAll();//先清空库(慎用!)jedis.set("key1","111");jedis.set("key2","222");jedis.set("key3","333");Set<String> keys = jedis.keys("*");System.out.println("查看所有key : "+keys);}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){//redisDemo.testSetAndGet(jedis);//redisDemo.delAndExixts(jedis);redisDemo.keys(jedis);}}
}
2.expire和ttl
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public static void expireAndttl(Jedis jedis) {jedis.flushAll();//先清空库(慎用!)jedis.set("key1","111");jedis.expire("key1", 10);try{Thread.sleep(3000);}catch (InterruptedException e){e.printStackTrace();}long time = jedis.ttl("key1");System.out.println("查看key1的存活时间 : "+time);}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){//redisDemo.testSetAndGet(jedis);//redisDemo.delAndExixts(jedis);//redisDemo.keys(jedis);redisDemo.expireAndttl(jedis);}}
}
2.5type
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public class redisDemo {public static void type(Jedis jedis){jedis.flushAll();//先清空库(慎用!)jedis.set("key1","111");//string类型String type = jedis.type("key1");System.out.println("查看key1的类型 : "+type);jedis.lpush("key2","222");//list类型String type1 = jedis.type("key2");System.out.println("查看key2的类型 : "+type1);jedis.hset("key3","name","王五");//hash类型String type2 =jedis.type("key3");System.out.println("查看key3的类型 : "+type2);jedis.zadd("key4",21,"zhangsan");//sorted set类型String type3 = jedis.type("key4");System.out.println("查看key4的类型 : "+type3);jedis.sadd("key5","set1","set2","set3");//set类型String type4 = jedis.type("key5");System.out.println("查看key5的类型 : "+type4);}public static void main(String[] args) {//连接Redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//从连接池中获取一个Jedis实例try(Jedis jedis = jedisPool.getResource()){//redisDemo.testSetAndGet(jedis);//redisDemo.delAndExixts(jedis);//redisDemo.keys(jedis);//redisDemo.expireAndttl(jedis);redisDemo.type(jedis);}}
}
三.String类型的通用命令
3.1mset和mget
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoString {public static void msetAndMset(Jedis jedis){jedis.mset("key1","111","key2","222","key3","333");List<String> value = jedis.mget("key1","key2","key3");System.out.println("接收mset返回值: "+value);}public static void main(String[] args) {//连接到redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//获取jedis对象Jedis jedis = jedisPool.getResource();//调用方法msetAndMset(jedis);}
}
3.2getrange 和 setrange
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoString {public static void msetAndMset(Jedis jedis){jedis.mset("key1","111","key2","222","key3","333");List<String> value = jedis.mget("key1","key2","key3");System.out.println("接收mset返回值: "+value);}public static void getrangeAndSetrange(Jedis jedis){jedis.set("key","hello redis world!");String result = jedis.get("key");System.out.println("接收get返回值: "+result);String value = jedis.getrange("key",6,11);System.out.println("接收getrange返回值: "+value);jedis.setrange("key",6,"hhhhh");String result2 = jedis.get("key");System.out.println("修改后的返回值: "+result2);}public static void main(String[] args) {//连接到redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//获取jedis对象Jedis jedis = jedisPool.getResource();//调用方法//msetAndMset(jedis);getrangeAndSetrange(jedis);}
}
3.3append
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoString {public static void append(Jedis jedis){jedis.flushAll();//清空redisjedis.set("key","hello");String value =jedis.get("key");System.out.println("初始值: "+value);jedis.append("key"," redis!");jedis.get("key");System.out.println("追加后的值: "+jedis.get("key"));}public static void main(String[] args) {//连接到redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//获取jedis对象Jedis jedis = jedisPool.getResource();//调用方法//msetAndMset(jedis);//getrangeAndSetrange(jedis);append(jedis);}
}
3.4incr和decr
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoString {public static void incrAndDecr(Jedis jedis){jedis.flushAll();jedis.set("key1","100");String value = jedis.get("key1");System.out.println("初始值: "+value);long vakeue = jedis.incr("key1");System.out.println("key1自增后的值: "+vakeue);long value2 = jedis.decr("key1");System.out.println("key1自减后的值: "+value2);}public static void main(String[] args) {//连接到redis服务器JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");//获取jedis对象Jedis jedis = jedisPool.getResource();//调用方法//msetAndMset(jedis);//getrangeAndSetrange(jedis);//append(jedis);incrAndDecr(jedis);//释放资源jedis.close();}
}
四.List类型的通用命令
4.1lpush和rpush
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoList {public static void lpushAndRpush(Jedis jedis){jedis.flushAll();jedis.lpush("key","111","222","333");List<String> result = jedis.lrange("key",0 ,-1);System.out.println("lpush result: " + result);jedis.rpush("key1","444","555","666");List<String> result1 = jedis.lrange("key1",0 ,-1);System.out.println("rpush result: " + result1);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = pool.getResource()) {lpushAndRpush(jedis);}}
}
4.2lpop和rpop
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoList {public static void lpopAndRpop(Jedis jedis){jedis.flushAll();jedis.lpush("key","111","222","333");List<String> res = jedis.lrange("key",0 ,-1);System.out.println("key value: "+res);String result1 = jedis.lpop("key");System.out.println("lpop result: " + result1);jedis.rpush("key1","444","555","666");List<String> res2 = jedis.lrange("key1",0 ,-1);System.out.println("key value: "+res2);String result2 = jedis.rpop("key1");System.out.println("rpop result: " + result2);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = pool.getResource()) {
// lpushAndRpush(jedis);lpopAndRpop(jedis);}}
}
4.3blpop和brpop
brpop与blpop同理,就不演示了
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoList {public static void blpop(Jedis jedis){jedis.flushAll();List<String> res = jedis.blpop(100,"key");System.out.println(res);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = pool.getResource()) {
// lpushAndRpush(jedis);//lpopAndRpop(jedis);blpop(jedis);}}
}
4.4llen
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class redisDemoList {public static void llen(Jedis jedis){jedis.flushAll();jedis.lpush("key","111","222","333");List<String> res = jedis.lrange("key",0,-1);System.out.println("key value: "+res);long result = jedis.llen("key");System.out.println("llen result: " + result);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = pool.getResource()) {
// lpushAndRpush(jedis);//lpopAndRpop(jedis);//blpop(jedis);llen(jedis);}}
}
五.Set类型的通用命令
5.1sadd和smember
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class redisDemoSet {public static void saddAndSmembers(Jedis jedis){jedis.flushAll();jedis.sadd("key","111","222","333");Set<String> res = jedis.smembers("key");System.out.println("key:value"+res);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){saddAndSmembers(jedis);}}
}
5.2sismember
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class redisDemoSet {public static void sismember(Jedis jedis){jedis.flushAll();jedis.sadd("key","111","222","333");Set<String> res =jedis.smembers("key");System.out.println("key:value"+res);System.out.println("key:222:"+jedis.sismember("key", "222"));System.out.println("key:444:"+jedis.sismember("key", "444"));}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){// saddAndSmembers(jedis);sismember(jedis);}}
}
5.3scard
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class redisDemoSet {public static void scard(Jedis jedis){jedis.flushAll();jedis.sadd("key","111","222","333");System.out.println(jedis.smembers("key"));System.out.println("获取长度"+jedis.scard("key"));}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){// saddAndSmembers(jedis);//sismember(jedis);scard(jedis);}}
}
5.4spop
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class redisDemoSet {public static void spop(Jedis jedis){jedis.flushAll();jedis.sadd("key","111","222","333","444","555");System.out.println(jedis.smembers("key"));String res = jedis.spop("key");System.out.println("随机弹出"+res);String res1 = jedis.spop("key");System.out.println("随机弹出"+res1);String res2 = jedis.spop("key");System.out.println("随机弹出"+res2);String res3 = jedis.spop("key");System.out.println("随机弹出"+res3);String res4 = jedis.spop("key");System.out.println("随机弹出"+res4);String res5 = jedis.spop("key");System.out.println("随机弹出"+res5);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){// saddAndSmembers(jedis);//sismember(jedis);//scard(jedis);spop(jedis);}}
}
5.5sinter和sinterstore
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class redisDemoSet {public static void sinterAndSinterstore(Jedis jedis){jedis.flushAll();jedis.sadd("key1","111","222","333");jedis.sadd("key2","222","555","444");Set<String> res = jedis.sinter("key1","key2");System.out.println("交集"+res);jedis.sinterstore("key3","key1","key2");System.out.println("key3的交集存储:"+jedis.smembers("key3"));}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){// saddAndSmembers(jedis);//sismember(jedis);//scard(jedis);//spop(jedis);sinterAndSinterstore(jedis);}}
}
六.Hash类型的通用命令
6.1hset和hget
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;public class redisDemoHash {public static void hsetAndHget(Jedis jedis){jedis.flushAll();jedis.hset("key1","name","zhangsan");HashMap<String,String> fields = new HashMap<>();fields.put("age","20");fields.put("gender","male");jedis.hset("key1",fields);String name = jedis.hget("key1","name");System.out.println(name);String age = jedis.hget("key1","age");System.out.println(age);String gender = jedis.hget("key1","gender");System.out.println(gender);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){hsetAndHget(jedis);}}
}
6.2hdel和hexists
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;public class redisDemoHash {public static void hdelAndhexists(Jedis jedis){jedis.flushAll();jedis.hset("key1","name","zhangsan");jedis.hset("key1","age","20");jedis.hset("key1","gender","male");long res = jedis.hdel("key1","age");System.out.println(res);boolean exists = jedis.hexists("key1","age");System.out.println(exists);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){//hsetAndHget(jedis);hdelAndhexists(jedis);}}
}
6.3hkeys和hvals
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.List;
import java.util.Set;public class redisDemoHash {public static void hkeysAndhvals(Jedis jedis){jedis.flushAll();jedis.hset("key1","name","zhangsan");jedis.hset("key1","age","20");jedis.hset("key1","gender","male");Set<String> keys = jedis.hkeys("key1");for(String key:keys){System.out.println(key);}List<String> vals = jedis.hvals("key1");for(String val:vals) {System.out.println(val);}}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){//hsetAndHget(jedis);//hdelAndhexists(jedis);hkeysAndhvals(jedis);}}
}
6.4hmset和hmget
(输出命令这是对应的)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.List;
import java.util.Set;public class redisDemoHash {public static void hmsertAndhmget(Jedis jedis){jedis.flushAll();HashMap<String,String> map = new HashMap<>();map.put("name","zhangsan");map.put("age","20");map.put("gender","male");jedis.hmset("key1",map);List<String> vals = jedis.hmget("key1","name","age","gender");System.out.println("vals: "+vals);}public static void main(String[] args) {JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = pool.getResource()){//hsetAndHget(jedis);//hdelAndhexists(jedis);//hkeysAndhvals(jedis);hmsertAndhmget(jedis);}}
}
七.Zset类型的通用命令
7.1zadd和zrange
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class redisDemoZset {public static void zaddAndZrange(Jedis jedis){jedis.zadd("key",30,"zhangsan");Map<String,Double> map = new HashMap<>();map.put("lisi",20.0);map.put("wangwu",10.0);jedis.zadd("key",map);List<String> members = jedis.zrange("key",0,-1);System.out.println(members);List<Tuple> membersWithScores = jedis.zrangeWithScores("key",0,-1);System.out.println(membersWithScores);}public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {zaddAndZrange(jedis);}}
}
7.2zcard
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class redisDemoZset {public static void zcard(Jedis jedis){jedis.flushAll();jedis.zadd("key",30,"zhangsan");jedis.zadd("key",20,"lisi");jedis.zadd("key",10,"wangwu");long count = jedis.zcard("key");System.out.println("获取key的元素数量:"+count);}public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {//zaddAndZrange(jedis);zcard(jedis);}}
}
7.3zrem
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class redisDemoZset {public static void zrem(Jedis jedis) {jedis.flushAll();jedis.zadd("key",30,"zhangsan");jedis.zadd("key",20,"lisi");jedis.zadd("key",10,"wangwu");System.out.println(jedis.zrangeWithScores("key", 0, -1));long count = jedis.zrem("key","lisi");System.out.println("删除key的元素lisi:"+count);System.out.println(jedis.zrangeWithScores("key", 0, -1));}public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {//zaddAndZrange(jedis);//zcard(jedis);zrem(jedis);}}
}
7.4zscore
注意代码55行返回类型是包装类Double不是double,要考虑返回为空的情况,double虽然也可以接收,但是如果返回为空,就会报空指针异常.
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class redisDemoZset {public static void zscore(Jedis jedis) {jedis.flushAll();jedis.zadd("key",30,"zhangsan");jedis.zadd("key",20,"lisi");jedis.zadd("key",10,"wangwu");System.out.println(jedis.zrangeWithScores("key", 0, -1));Double score = jedis.zscore("key","lisi");System.out.println("获取key的元素lisi的分数:"+score);}public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {//zaddAndZrange(jedis);//zcard(jedis);//zrem(jedis);zscore(jedis);}}
}
7.5zrank
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class redisDemoZset {public static void zrank(Jedis jedis) {jedis.flushAll();jedis.zadd("key",30,"zhangsan");jedis.zadd("key",20,"lisi");jedis.zadd("key",10,"wangwu");System.out.println(jedis.zrangeWithScores("key", 0, -1));Long rank = jedis.zrank("key","lisi");System.out.println("获取key的元素lisi的排名:"+rank);}public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {//zaddAndZrange(jedis);//zcard(jedis);//zrem(jedis);// zscore(jedis);zrank(jedis);}}
}
八.Spring项目应用redis
1.创建Spring项目
1.配置文件(修改yml后缀)填写redis修改配置
8.1String


package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Controller {@Autowiredprivate StringRedisTemplate redisTemplate;@GetMapping("/testString")public String testString() {redisTemplate.opsForValue().set("key", "Hello Redis!");//获取的是String类型的对象String value = redisTemplate.opsForValue().get("key");//获取的是String类型的对象System.out.println(value);return "OK";}}
8.2List
@GetMapping("/testList")@ResponseBodypublic String testList() {// 先清除之前的数据.redisTemplate.execute((RedisConnection connection) -> {// execute 要求回调方法中必须写 return 语句. 返回个东西.// 这个回调返回的对象, 就会作为 execute 本身的返回值.connection.flushAll();return null;});redisTemplate.opsForList().leftPush("key", "111");redisTemplate.opsForList().leftPush("key", "222");redisTemplate.opsForList().leftPush("key", "333");String value = redisTemplate.opsForList().rightPop("key");System.out.println("value: " + value);value = redisTemplate.opsForList().rightPop("key");System.out.println("value: " + value);value = redisTemplate.opsForList().rightPop("key");System.out.println("value: " + value);return "OK";}
- 清空 Redis 数据:使用 `redisTemplate.execute` 执行 `flushAll()`,清除所有 key,保证测试环境干净。
- 向列表写入数据:使用 `leftPush` 向名为 `"key"` 的列表依次插入 `"111"`、`"222"`、`"333"`,最终列表为 `["333", "222", "111"]`。
- 从列表读取数据:使用 `rightPop` 从右侧依次弹出值,获取顺序为 `"111"`、`"222"`、`"333"`,并输出到控制台。
8.3Set
@GetMapping("/testSet")@ResponseBodypublic String testSet() {redisTemplate.execute((RedisConnection connection) -> {connection.flushAll();return null;});redisTemplate.opsForSet().add("key", "111", "222", "333");Set<String> result = redisTemplate.opsForSet().members("key");System.out.println("result: " + result);Boolean exists = redisTemplate.opsForSet().isMember("key", "111");System.out.println("exists: " + exists);Long count = redisTemplate.opsForSet().size("key");System.out.println("count: " + count);redisTemplate.opsForSet().remove("key", "111", "222");result = redisTemplate.opsForSet().members("key");System.out.println("result: " + result);return "OK";}
- 初始化与添加数据:先通过 flushAll() 清空 Redis,再使用 opsForSet().add 向集合 "key" 添加元素 "111"、"222"、"333"。
- 集合操作与查询:通过 members 获取集合中所有元素,isMember 判断某个元素是否存在,size 获取集合元素数量。
- 删除元素:使用 remove 删除集合中的 "111" 和 "222",再次通过 members 输出剩余元素。
8.4Hash
@GetMapping("/testHash")@ResponseBodypublic String testHash() {redisTemplate.execute((RedisConnection connection) -> {connection.flushAll();return null;});redisTemplate.opsForHash().put("key", "f1", "111");redisTemplate.opsForHash().put("key", "f2", "222");redisTemplate.opsForHash().put("key", "f3", "333");String value = (String) redisTemplate.opsForHash().get("key", "f1");System.out.println("value: " + value);Boolean exists = redisTemplate.opsForHash().hasKey("key", "f1");System.out.println("exists: " + exists);redisTemplate.opsForHash().delete("key", "f1", "f2");Long size = redisTemplate.opsForHash().size("key");System.out.println("size: " + size);return "OK";}
- 初始化与添加字段:清空 Redis 后,使用 opsForHash().put 向名为 "key" 的哈希结构添加字段 "f1"、"f2"、"f3" 分别对应值 "111"、"222"、"333"。
- 查询与判断存在性:使用 get 获取字段 "f1" 的值,用 hasKey 判断 "f1" 是否存在。
- 删除字段与获取大小:通过 delete 删除字段 "f1" 和 "f2",再使用 size 获取哈希表剩余字段数量
8.5Zset
@GetMapping("/testZSet")@ResponseBodypublic String testZSet() {redisTemplate.execute((RedisConnection connection) -> {connection.flushAll();return null;});redisTemplate.opsForZSet().add("key", "zhangsan", 10);redisTemplate.opsForZSet().add("key", "lisi", 20);redisTemplate.opsForZSet().add("key", "wangwu", 30);Set<String> members = redisTemplate.opsForZSet().range("key", 0, -1);System.out.println("members: " + members);Set<ZSetOperations.TypedTuple<String>> membersWithScore = redisTemplate.opsForZSet().rangeWithScores("key", 0, -1);System.out.println("membersWithScore: " + membersWithScore);Double score = redisTemplate.opsForZSet().score("key", "zhangsan");System.out.println("score: " + score);redisTemplate.opsForZSet().remove("key", "zhangsan");Long size = redisTemplate.opsForZSet().size("key");System.out.println("size: " + size);Long rank = redisTemplate.opsForZSet().rank("key", "lisi");System.out.println("rank: " + rank);return "OK";}
- 添加与查询成员:通过 add 向有序集合 "key" 添加带分数的元素(如 "zhangsan" 分数为 10),使用 range 和 rangeWithScores 获取元素及其分数。
- 查询分数与删除元素:用 score 查询某元素的分数,用 remove 删除指定成员(如 "zhangsan")。
- 集合统计信息:使用 size 获取 ZSet 中元素总数,rank 查询指定成员(如 "lisi")的排名(从 0 开始)。