当前位置: 首页 > ops >正文

redis-----java客户端

一、引入jedis依赖

Maven Repository: redis.clients » jedis

      <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.2.0</version></dependency>

二、关于开放redis端口的问题

java开发代码,高度依赖于Windows(IDEA)

我们Windows客户端想要访问redis服务器,就需要通过云服务器的外网IP来访问linux服务器,我们会想到修改外网IP,但是这是不够,redis的6379端口,默认是被云服务器的防火墙保护起来的,不能被外面访问,但是我们也访问不了,就可以在云服务器后台把防火墙6379端口放开,这样是不可以的,因为redis端口一旦公开在公网上,很容易被黑客攻击入侵
虽然tomcat端口也放开了,但是tomcat的端口是不容易被入侵的,但是redis的6379端口就很容易被入侵,所以我们想不开放redis端口,又想通过外网访问,我们就可以:
1. 把java程序放在linux上运行,把代码打成jar包,把jar包放到linux服务器上执行,手续比较繁琐
2. 配置ssh端口转发,把云服务器的redis端口,映射到本地主机

简单来说,ssh服务程序相当于一个送外卖的,Windows主机和linux服务器相当于商家和客户,通过外卖小哥(ssh)将对应单号(端口号)送到对应的用户手上

映射redis端口到本地

在本地的cmd输入netstat -ano | findstr 8888,看看端口转发是否配置成功

三、连接redis服务器

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 ping = jedis.ping();System.out.println(ping);}}
}

代码中 try 的写法是 try-with-resources 语法,这是 Java 7 引入的一种异常处理机制,主要用于 自动释放资源,特别适合处理实现了 AutoCloseable 接口的资源(如文件流、数据库连接、网络连接等)。

具体分析这段代码:

java

运行

try(Jedis jedis = jedisPool.getResource()) {String ping = jedis.ping();System.out.println(ping);
}
1. 语法特点:
  • 在 try 关键字后的括号 () 中声明资源(这里是 Jedis 对象)。
  • 资源必须实现 AutoCloseable 接口(Jedis 间接实现了该接口)。
  • 代码块执行完毕后,无需手动调用 close() 方法,Java 会自动释放资源。
2. 优势:
  • 简化代码:避免了传统 try-finally 中手动关闭资源的繁琐(如 jedis.close())。
  • 确保资源释放:即使代码块中发生异常,资源也能被可靠释放,防止资源泄露。
  • 可读性更好:资源声明与释放逻辑分离,代码更清晰。
对比传统写法:

如果不用 try-with-resources,需要手动关闭资源:

 
Jedis jedis = null;
try {jedis = jedisPool.getResource();String ping = jedis.ping();System.out.println(ping);
} finally {if (jedis != null) {jedis.close(); // 手动关闭资源}
}

 

显然,try-with-resources 写法更简洁且安全,因此在处理需要关闭的资源时(如 Redis 连接、数据库连接等)非常推荐使用。

JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");

这里的ip和端口号仅限于当前的开发阶段,后续如果我们的程序需要部署到与服务器上,就得按照与服务器的实际情况来写

文件在etc/redis/redis.conf

四、使用命令

1.通用命令

1.set,get

//清空数据库jedis.flushAll();//设置数据jedis.set("key","1111");//获取数据String val = jedis.get("key");System.out.println(val);System.out.println("----------------------");//设置数据超时时间jedis.setex("key1",1,"设置超时时间的1111");//获取数据String val1 = jedis.get("key1");System.out.println(val1);Thread.sleep(2000);//2秒后获取数据String val2 = jedis.get("key1");System.out.println(val2);System.out.println("----------------------");SetParams params=new SetParams();//设置超时时间params.ex(1);//不存在才能设置成功params.nx();//存在才能设置成功params.xx();jedis.set("key2","设置超时时间的2222",params);

2.exists,del

    public static void test2(Jedis jedis){jedis.set("key","1111");jedis.set("key1","222");jedis.set("key2","333");jedis.set("key3","444");//判断key是否存在Boolean exists = jedis.exists("key");System.out.println(exists);//删除keyLong del = jedis.del("key");//判断key是否存在exists = jedis.exists("key");System.out.println(exists);System.out.println("----------------------");//删除多个数据Long del1 = jedis.del("key1", "key2", "key3");}

3.keys *

Set<String> keys = jedis.keys("*");

4.expire,ttl,type

public static void test1(Jedis jedis) throws InterruptedException {
jedis.set("key","1111");
//设置超时时间
jedis.expire("key",10);
Thread.sleep(2000);
//获取超时剩余时间System.out.println(jedis.ttl("key"));
//获取数据类型System.out.println(jedis.type("key"));Thread.sleep(9000);
//判断key是否存在boolean key = jedis.exists("key");System.out.println(key);System.out.println("----------------------");
//获取数据类型jedis.lpush("list","1111","2222","3333");System.out.println(jedis.type("list"));
}

2.String命令

1.mset,mget

public static void test3(Jedis jedis){jedis.mset("key1","1111","key2","2222","key3","3333");List<String> mget = jedis.mget("key1", "key2", "key3");System.out.println(mget);
}

mget中有几个key就返回几个元素,没有key就返回null

2.setrange,getrange

 jedis.set("key1","abcdefgh");//截取字符串System.out.println(jedis.getrange("key1", 0, 2));//修改字符串jedis.setrange("key1", 2, "12");System.out.println(jedis.get("key1"));

3.append,incr,decr,incrBy,decrBy

  jedis.set("key1","1111");//追加字符串jedis.append("key1","2222");System.out.println(jedis.get("key1"));System.out.println("----------------------");jedis.set("key2","100");//自增jedis.incr("key2");System.out.println(jedis.get("key2"));//自增指定值jedis.incrBy("key2",2);System.out.println(jedis.get("key2"));//自减jedis.decr("key2");System.out.println(jedis.get("key2"));//自减指定值jedis.decrBy("key2",2);System.out.println(jedis.get("key2"));

3.list命令

public static void test4(Jedis jedis){jedis.lpush("list","1111","2222","3333");//获取列表长度System.out.println(jedis.llen("list"));//获取列表数据List<String> list = jedis.lrange("list", 0, -1);System.out.println(list);//删除列表数据Long lrem = jedis.lrem("list", 1, "2222");System.out.println(lrem);//删除左元素String lpop = jedis.lpop("list");System.out.println(lpop);//删除右元素String rpop = jedis.rpop("list");System.out.println(rpop);//阻塞删除List<String> list1 = jedis.brpop(0, "list");System.out.println(list1);
}

4.set命令

public static void test5(Jedis jedis){jedis.sadd("set","1111","2222","3333");jedis.sadd("set2","1111","2222","4444","5555");//获取集合长度System.out.println(jedis.scard("set"));//获取集合数据Set<String> set = jedis.smembers("set");System.out.println(set);//判断元素是否存在Boolean sismember = jedis.sismember("set", "1111");System.out.println(sismember);//删除元素Long srem = jedis.srem("set", "1111");System.out.println(srem);//并集Set<String> union = jedis.sunion("set", "set2");System.out.println(union);//交集Set<String> intersect = jedis.sinter("set", "set2");System.out.println(intersect);//差集Set<String> diff = jedis.sdiff("set", "set2");System.out.println(diff);
}

5.hash命令

public static void test6(Jedis jedis){jedis.hset("hash","key1","1111");jedis.hset("hash","key2","2222");//获取hash长度System.out.println(jedis.hlen("hash"));//获取hash数据System.out.println(jedis.hgetAll("hash"));//获取hash指定key的值System.out.println(jedis.hget("hash","key1"));//判断hash指定key是否存在System.out.println(jedis.hexists("hash","key1"));//删除hash指定keySystem.out.println(jedis.hdel("hash","key1"));//获取hash所有keySystem.out.println(jedis.hkeys("hash"));//获取hash所有valueSystem.out.println(jedis.hvals("hash"));//设置多个hash值jedis.hmset("hash", Map.of("key3","3333","key4","4444"));//获取多个hash值System.out.println(jedis.hmget("hash","key3","key4"));
}

6.zset命令

public static void test7(Jedis jedis){jedis.zadd("zset",1,"1111");jedis.zadd("zset",2,"2222");jedis.zadd("zset",3,"3333");//获取有序集合长度System.out.println(jedis.zcard("zset"));//获取有序集合数据System.out.println(jedis.zrange("zset",0,-1));//获取有序集合指定分数区间的元素System.out.println(jedis.zrangeByScore("zset",0,2));//获取有序集合指定分数区间的元素个数System.out.println(jedis.zcount("zset",0,2));//删除有序集合指定元素System.out.println(jedis.zrem("zset","1111"));//获取有序集合指定元素的分数System.out.println(jedis.zscore("zset","2222"));//获取有序集合指定元素的排名System.out.println(jedis.zrank("zset","3333"));//获取有序集合指定元素的排名System.out.println(jedis.zrevrank("zset","3333"));
}

五、javaSpring客户端

1.创建项目引入redis依赖

配置ip地址和端口号

2.StringRedisTemplate

StringRedisTemplate 是 Spring Data Redis 框架中的一个类,用于在 Spring 应用程序中方便地操作 Redis 数据库,专门处理字符串类型的数据。以下是关于它的详细介绍:

继承关系和作用

StringRedisTemplate 继承自 RedisTemplate ,RedisTemplate 是 Spring 对 Redis 各种操作的通用封装,支持 Redis 所有数据结构的操作。而 StringRedisTemplate 是对 RedisTemplate 的一种特殊化,将键和值的序列化方式默认设置为字符串序列化,使得在处理字符串类型数据时更加便捷,无需额外配置序列化器 。

主要方法

  • 存储数据
    • opsForValue().set(String key, String value):向 Redis 中以指定的 key 存储对应的 value ,例如 stringRedisTemplate.opsForValue().set("username", "John"); ,就将键为 "username" ,值为 "John" 的键值对存入 Redis 。
    • opsForValue().set(String key, String value, long timeout, TimeUnit unit):除了设置键值对,还可以设置过期时间,如 stringRedisTemplate.opsForValue().set("token", "abc123", 60, TimeUnit.MINUTES); ,表示 "token" 这个键对应的值 "abc123" 在 60 分钟后过期 。
  • 获取数据
    • opsForValue().get(String key):根据指定的 key 从 Redis 中获取对应的值,例如 String name = stringRedisTemplate.opsForValue().get("username"); 。
  • 删除数据
    • delete(String key):根据 key 删除 Redis 中对应的键值对,比如 stringRedisTemplate.delete("token"); 。

使用示例

在 Spring Boot 项目中,先确保引入了 Spring Data Redis 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在控制器类或服务类中就可以通过依赖注入的方式使用 StringRedisTemplate :

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;import java.util.concurrent.TimeUnit;@RestController
public class RedisController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@GetMapping("/setData")public String setData() {stringRedisTemplate.opsForValue().set("message", "Hello Redis!", 10, TimeUnit.MINUTES);return "Data set successfully";}@GetMapping("/getData")public String getData() {return stringRedisTemplate.opsForValue().get("message");}
}

在上述示例中,通过两个接口分别演示了使用 StringRedisTemplate 向 Redis 存储带有过期时间的数据,以及从 Redis 中获取数据的操作。

3.使用String

    @RequestMapping("/testString")@ResponseBodypublic String testString() {redisTemplate.opsForValue().set("key","value");redisTemplate.opsForValue().set("key2","value2");String s = redisTemplate.opsForValue().get("key");System.out.println(s);return "ok:"+s;}

4.使用list

    @RequestMapping("/testList")@ResponseBodypublic String testList() {redisTemplate.opsForList().leftPush("list","value");redisTemplate.opsForList().leftPush("list","value2");String s = redisTemplate.opsForList().leftPop("list");System.out.println(s);return "ok:"+s;}

5.使用hash

 @RequestMapping("/testHash")@ResponseBodypublic String testHash() {redisTemplate.opsForHash().put("hash","key","value");redisTemplate.opsForHash().put("hash","key2","value2");String s = (String) redisTemplate.opsForHash().get("hash","key");System.out.println(s);return "ok:"+s;}

6.使用set

    @RequestMapping("/testSet")@ResponseBodypublic String testSet() {redisTemplate.opsForSet().add("set","value");redisTemplate.opsForSet().add("set","value2");String s = (String) redisTemplate.opsForSet().pop("set");System.out.println(s);return "ok:"+s;}

7.使用zset

    @RequestMapping("/testZSet")@ResponseBodypublic String testZSet() {redisTemplate.opsForZSet().add("zset","value",1);redisTemplate.opsForZSet().add("zset","value2",2);redisTemplate.opsForZSet().count("zset",1,2);redisTemplate.opsForZSet().rank("zset","value");return "ok:"+redisTemplate.opsForZSet().count("zset",1,2);}

8.对于StringRedisTemplate没有封装的方法,怎么调用底层的redis方法

    @RequestMapping("/test")@ResponseBodypublic String test() {redisTemplate.execute((RedisConnection connection) -> {connection.flushAll();return null;});
return "通过execute方法调用redis的api,也就是Jedis";}

通过 Spring Data Redis 提供的 RedisTemplate 来执行底层 Redis 命令,直接操作 Redis 连接对象(RedisConnection),这种方式可以访问一些高级或底层的 Redis 功能。

http://www.xdnf.cn/news/19508.html

相关文章:

  • K8s集群+Rancher Server:部署DolphinScheduler 3.2.2集群
  • 【vue2】vue2.7x的项目中集成tailwind.css真的不要太香
  • GPT-5在医疗领域应用的研究效能初探(上)
  • Elasticsearch赋能3D打印机任务统计分析
  • 【图像处理基石】图像预处理方面有哪些经典的算法?
  • 聚铭网络实力蝉联数说安全“2025年中国网络安全市场100强”
  • 【C++游记】红黑树
  • Lombok 实用注解深度解析!
  • 【项目】多模态RAG—本地部署MinerU实现多类文档解析
  • 懒加载详细讲解
  • 使用修改过的arj源码编译和测试
  • C++ 学习与 CLion 使用:(五)数据类型,包括整型、实型、字符型、转义字符、字符串、布尔型
  • 从DevOps到BizDevOps:哪些DevOps工具能够成为业务创新加速引擎?
  • 响应式编程框架Reactor【8】
  • Notepad++近期版本避雷
  • 中心扩展算法
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘tox’问题
  • 利用 DrissionPage 精准获取淘宝商品描述:Python 爬虫实战指南
  • C/C++、Python和Java语言的比较
  • 【职业】算法与数据结构专题
  • 15693协议ICODE SLI 系列标签应用场景说明及读、写、密钥认证操作Qt c++源码,支持统信、麒麟等国产Linux系统
  • 浪潮科技Java开发面试题及参考答案(120道题-上)
  • 利用本地电脑上的MobaXterm连接虚拟机上的Ubuntu
  • 基于SpringBoot音乐翻唱平台
  • Linux Shell 脚本中括号类型及用途
  • three.js+WebGL踩坑经验合集(10.2):镜像问题又一坑——THREE.InstancedMesh的正反面向光问题
  • UART-TCP双向桥接服务
  • 【51单片机三路抢答器定时器1工作1外部中断1】2022-11-24
  • 参数检验vs非参数检验
  • docker 网络配置