Java 接入Redis: 使用Jedis操作Redis

Jedis: Java客户端三步操作模型与命令方法映射

纲要

本文解决「在 Java 程序中如何操作 Redis」的问题。以 Jedis 为切入点,建立「命令即方法」的映射认知,为后续 Spring Data Redis 打基础。

  • Java 操作 Redis 的技术栈
    • Redis 官方推荐三种客户端:JedisLettuceRedisson
    • Spring 整合方案:Spring Data Redis
    • Spring Boot 起步依赖:spring-boot-starter-data-redis
  • Jedis 三步模型
    • 获取连接 → 执行操作 → 关闭连接(类比 JDBC
  • 核心认知
    • Jedis 的方法名与 Redis 命令完全一致
  • 实操覆盖
    • stringset / get / del
    • hashhset / hget
    • 通用:keys *
  • 工程化补充
    • JedisPool 连接池

Java 操作 Redis 的技术选型

Redis 的 Java 客户端非常多,Redis 官方推荐的有三种:
#mermaid-svg-61EyIRAK9ePbhnWx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-61EyIRAK9ePbhnWx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-61EyIRAK9ePbhnWx .error-icon{fill:#552222;}#mermaid-svg-61EyIRAK9ePbhnWx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-61EyIRAK9ePbhnWx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-61EyIRAK9ePbhnWx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-61EyIRAK9ePbhnWx .marker.cross{stroke:#333333;}#mermaid-svg-61EyIRAK9ePbhnWx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-61EyIRAK9ePbhnWx p{margin:0;}#mermaid-svg-61EyIRAK9ePbhnWx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-61EyIRAK9ePbhnWx .cluster-label text{fill:#333;}#mermaid-svg-61EyIRAK9ePbhnWx .cluster-label span{color:#333;}#mermaid-svg-61EyIRAK9ePbhnWx .cluster-label span p{background-color:transparent;}#mermaid-svg-61EyIRAK9ePbhnWx .label text,#mermaid-svg-61EyIRAK9ePbhnWx span{fill:#333;color:#333;}#mermaid-svg-61EyIRAK9ePbhnWx .node rect,#mermaid-svg-61EyIRAK9ePbhnWx .node circle,#mermaid-svg-61EyIRAK9ePbhnWx .node ellipse,#mermaid-svg-61EyIRAK9ePbhnWx .node polygon,#mermaid-svg-61EyIRAK9ePbhnWx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-61EyIRAK9ePbhnWx .rough-node .label text,#mermaid-svg-61EyIRAK9ePbhnWx .node .label text,#mermaid-svg-61EyIRAK9ePbhnWx .image-shape .label,#mermaid-svg-61EyIRAK9ePbhnWx .icon-shape .label{text-anchor:middle;}#mermaid-svg-61EyIRAK9ePbhnWx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-61EyIRAK9ePbhnWx .rough-node .label,#mermaid-svg-61EyIRAK9ePbhnWx .node .label,#mermaid-svg-61EyIRAK9ePbhnWx .image-shape .label,#mermaid-svg-61EyIRAK9ePbhnWx .icon-shape .label{text-align:center;}#mermaid-svg-61EyIRAK9ePbhnWx .node.clickable{cursor:pointer;}#mermaid-svg-61EyIRAK9ePbhnWx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-61EyIRAK9ePbhnWx .arrowheadPath{fill:#333333;}#mermaid-svg-61EyIRAK9ePbhnWx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-61EyIRAK9ePbhnWx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-61EyIRAK9ePbhnWx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-61EyIRAK9ePbhnWx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-61EyIRAK9ePbhnWx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-61EyIRAK9ePbhnWx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-61EyIRAK9ePbhnWx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-61EyIRAK9ePbhnWx .cluster text{fill:#333;}#mermaid-svg-61EyIRAK9ePbhnWx .cluster span{color:#333;}#mermaid-svg-61EyIRAK9ePbhnWx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-61EyIRAK9ePbhnWx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-61EyIRAK9ePbhnWx rect.text{fill:none;stroke-width:0;}#mermaid-svg-61EyIRAK9ePbhnWx .icon-shape,#mermaid-svg-61EyIRAK9ePbhnWx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-61EyIRAK9ePbhnWx .icon-shape p,#mermaid-svg-61EyIRAK9ePbhnWx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-61EyIRAK9ePbhnWx .icon-shape .label rect,#mermaid-svg-61EyIRAK9ePbhnWx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-61EyIRAK9ePbhnWx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-61EyIRAK9ePbhnWx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-61EyIRAK9ePbhnWx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Redis Java 客户端
官方推荐
Spring 生态
Jedis

轻量、同步阻塞

方法名与命令一致
Lettuce

基于 Netty、线程安全

Spring Boot 2.x 默认
Redisson

分布式对象与服务

分布式锁、延迟队列
Spring Data Redis

统一抽象层
spring-boot-starter-data-redis

客户端 特点 适用场景
Jedis 轻量、同步阻塞 、API 与 Redis 命令一一对应 学习入门、简单场景
Lettuce 基于 Netty连接实例线程安全、支持异步与响应式 高并发生产环境(Spring Boot 2.x 起为默认)
Redisson 提供分布式对象与服务封装 分布式锁、分布式集合等高级特性

Spring 框架对 Redis 客户端做了整合,提供 Spring Data RedisSpring Boot 项目则进一步提供起步依赖 spring-boot-starter-data-redis,引入即用。

本文先以 Jedis 做快速验证,后续重点转向 Spring Data Redis------因为实际项目绝大多数基于 Spring Boot 构建。

Jedis 的三步操作模型

使用 Jedis 只有三步,与 JDBC 操作 MySQL 的套路完全一致:
#mermaid-svg-rDA2qz8jzlwT9E7f{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rDA2qz8jzlwT9E7f .error-icon{fill:#552222;}#mermaid-svg-rDA2qz8jzlwT9E7f .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rDA2qz8jzlwT9E7f .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rDA2qz8jzlwT9E7f .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rDA2qz8jzlwT9E7f .marker.cross{stroke:#333333;}#mermaid-svg-rDA2qz8jzlwT9E7f svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rDA2qz8jzlwT9E7f p{margin:0;}#mermaid-svg-rDA2qz8jzlwT9E7f .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster-label text{fill:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster-label span{color:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster-label span p{background-color:transparent;}#mermaid-svg-rDA2qz8jzlwT9E7f .label text,#mermaid-svg-rDA2qz8jzlwT9E7f span{fill:#333;color:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f .node rect,#mermaid-svg-rDA2qz8jzlwT9E7f .node circle,#mermaid-svg-rDA2qz8jzlwT9E7f .node ellipse,#mermaid-svg-rDA2qz8jzlwT9E7f .node polygon,#mermaid-svg-rDA2qz8jzlwT9E7f .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rDA2qz8jzlwT9E7f .rough-node .label text,#mermaid-svg-rDA2qz8jzlwT9E7f .node .label text,#mermaid-svg-rDA2qz8jzlwT9E7f .image-shape .label,#mermaid-svg-rDA2qz8jzlwT9E7f .icon-shape .label{text-anchor:middle;}#mermaid-svg-rDA2qz8jzlwT9E7f .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rDA2qz8jzlwT9E7f .rough-node .label,#mermaid-svg-rDA2qz8jzlwT9E7f .node .label,#mermaid-svg-rDA2qz8jzlwT9E7f .image-shape .label,#mermaid-svg-rDA2qz8jzlwT9E7f .icon-shape .label{text-align:center;}#mermaid-svg-rDA2qz8jzlwT9E7f .node.clickable{cursor:pointer;}#mermaid-svg-rDA2qz8jzlwT9E7f .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rDA2qz8jzlwT9E7f .arrowheadPath{fill:#333333;}#mermaid-svg-rDA2qz8jzlwT9E7f .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rDA2qz8jzlwT9E7f .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rDA2qz8jzlwT9E7f .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rDA2qz8jzlwT9E7f .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rDA2qz8jzlwT9E7f .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rDA2qz8jzlwT9E7f .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster text{fill:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f .cluster span{color:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rDA2qz8jzlwT9E7f .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rDA2qz8jzlwT9E7f rect.text{fill:none;stroke-width:0;}#mermaid-svg-rDA2qz8jzlwT9E7f .icon-shape,#mermaid-svg-rDA2qz8jzlwT9E7f .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rDA2qz8jzlwT9E7f .icon-shape p,#mermaid-svg-rDA2qz8jzlwT9E7f .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rDA2qz8jzlwT9E7f .icon-shape .label rect,#mermaid-svg-rDA2qz8jzlwT9E7f .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rDA2qz8jzlwT9E7f .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rDA2qz8jzlwT9E7f .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rDA2qz8jzlwT9E7f :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1. 获取连接

new Jedis(host, port)
2. 执行操作

jedis.set / get / hset ...
3. 关闭连接

jedis.close()

步骤 JDBC 对应物 Jedis 实现
获取连接 Connection new Jedis(host, port)
执行操作 Statement.execute() jedis.set() / jedis.get()
关闭连接 connection.close() jedis.close()

引入依赖

xml 复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.0</version>
</dependency>

核心认知:方法名即命令名

这是学习 Jedis 最省力的一点:Jedis 中的方法名与 Redis 命令完全一致

Redis 命令 Jedis 方法
SET key value jedis.set(key, value)
GET key jedis.get(key)
DEL key jedis.del(key)
HSET key field value jedis.hset(key, field, value)
HGET key field jedis.hget(key, field)
KEYS * jedis.keys("*")

因此只要掌握了 Redis 命令,Jedis 的 API 无需额外记忆------Jedis 底层就是把 Java 方法调用翻译成 Redis 命令发给服务端。

实操演示

建立连接

java 复制代码
// host:Redis 服务器 IP,本地即 localhost
// port:Redis 端口,默认 6379
Jedis jedis = new Jedis("localhost", 6379);

前置条件 :必须先启动 Redis 服务。若服务未启动,执行时会抛出连接超时异常 connect timed out

string 类型操作

java 复制代码
// SET username xiaoming
jedis.set("username", "xiaoming");

// GET username
String value = jedis.get("username");
System.out.println(value);

// DEL username
jedis.del("username");

执行后在 redis-cli 中验证:

bash 复制代码
127.0.0.1:6379> GET username
(nil)

删除后返回 nil,说明 del 生效。

hash 类型操作

java 复制代码
// HSET myhash addr bj
jedis.hset("myhash", "addr", "bj");

// HGET myhash addr
String hValue = jedis.hget("myhash", "addr");
System.out.println(hValue);

参数顺序与命令完全对应:keyfieldvalue

通用操作

java 复制代码
// KEYS *
Set<String> keys = jedis.keys("*");
for (String key : keys) {
    System.out.println(key);
}

返回值为 Set<String>,遍历即可列出全部 key

关闭连接

java 复制代码
jedis.close();

完整可运行代码

原始测试代码

java 复制代码
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. 获取连接
        Jedis jedis = new Jedis("localhost", 6379);

        // 2. 执行具体操作
        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();
    }
}

pom.xml

xml 复制代码
<?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>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.0</version>
        </dependency>
    </dependencies>
</project>

工程目录结构

txt 复制代码
jedis_demo/
├── pom.xml                                  # 仅依赖 junit + jedis
└── src/
    └── test/
        └── java/com/itheima/test/
            └── JedisTest.java               # Jedis 三步操作示例

工程化版本:Jedis 连接池

生产环境不应每次操作都新建连接,应使用 JedisPool 复用连接。

java 复制代码
package com.itheima.test;

import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Set;

/**
 * 使用 Jedis 连接池操作 Redis。
 * 生产环境必须使用连接池,避免频繁创建销毁连接带来的开销。
 */
public class JedisPoolTest {

    /**
     * 演示 string、hash 与通用操作,连接从连接池获取。
     */
    @Test
    public void testWithPool() {
        // 1. 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10);      // 最大连接数
        poolConfig.setMaxIdle(5);        // 最大空闲连接数
        poolConfig.setMinIdle(2);        // 最小空闲连接数
        poolConfig.setMaxWaitMillis(3000); // 获取连接的最大等待毫秒数
        poolConfig.setTestOnBorrow(true);  // 获取连接时做有效性检测

        // 2. 创建连接池:host、port、超时、密码(无密码则传 null)
        try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379, 3000, null);
             Jedis jedis = jedisPool.getResource()) {

            // string 操作
            jedis.set("username", "xiaoming");
            System.out.println("GET username -> " + jedis.get("username"));

            // hash 操作
            jedis.hset("myhash", "addr", "bj");
            System.out.println("HGET myhash addr -> " + jedis.hget("myhash", "addr"));

            // 通用操作
            Set<String> keys = jedis.keys("*");
            System.out.println("KEYS * -> " + keys);

            // 清理
            jedis.del("username", "myhash");
        }
    }
}

JedisPoolJedis 都实现了 AutoCloseableJedis 在较新版本中),使用 try-with-resources 可确保连接正确归还/释放。

API 速览

Jedis API 对应 Redis 命令 说明
new Jedis(host, port) --- 创建连接
jedis.set(k, v) SET 设置字符串值
jedis.get(k) GET 获取字符串值
jedis.del(k...) DEL 删除键
jedis.setex(k, sec, v) SETEX 带过期时间设置
jedis.setnx(k, v) SETNX 不存在才设置
jedis.hset(k, f, v) HSET 设置哈希字段
jedis.hget(k, f) HGET 获取哈希字段
jedis.hgetAll(k) HGETALL 获取全部字段与值
jedis.lpush(k, v...) LPUSH 列表左侧插入
jedis.rpop(k) RPOP 列表右侧弹出
jedis.sadd(k, m...) SADD 集合添加成员
jedis.zadd(k, score, m) ZADD 有序集合添加
jedis.keys(pattern) KEYS 模式匹配查询键
jedis.exists(k) EXISTS 判断键是否存在
jedis.ttl(k) TTL 剩余存活时间
jedis.auth(password) AUTH 密码认证
jedis.close() --- 关闭连接
new JedisPool(config, host, port, timeout, password) --- 创建连接池

官方文档

总结

本文建立了「在 Java 中操作 Redis」的第一层认知:技术选型上官方推荐 JedisLettuceRedisson 三种客户端,Spring Boot 项目则统一走 spring-boot-starter-data-redisJedis 的用法是标准的三步模型------获取连接、执行操作、关闭连接,与 JDBC 完全同构;其最大特点是方法名与 Redis 命令一一对应set/get/del/hset/hget/keys),因此命令学扎实后客户端 API 几乎零学习成本。工程化使用时需改用 JedisPool 复用连接,避免每次操作新建带来的开销。

相关推荐
事圆则缓2 小时前
Java 8 Lambda、Stream、Optional 与 Android 边界:从回调语法到运行时兼容
android·java
shehuiyuelaiyuehao2 小时前
算法50,分治归并,数组中的逆序对
java·算法
烽学长2 小时前
(附源码)基于Springboot+vue的图书阅读分享系统的设计与实现
java·spring boot·后端
Ivanqhz2 小时前
数据搬运是性能关键
java·服务器·网络·人工智能·深度学习
其实防守也摸鱼2 小时前
常见安全架构中 Shiro 的认证确认机制解析
运维·服务器·数据库·windows·github
青山木2 小时前
RocketMQ 入门到原理(三):消息存储原理
java·后端·中间件·架构·rocketmq
MayBaymax2 小时前
Spring AI Alibaba Graph 实战:客服工单智能处理
java·ai·ai编程
Julien20042 小时前
自动挂载网络附加存储
linux·服务器·网络
光依旧3 小时前
MCP实战手记系列(五):让工具返回一个能点的界面(文末附github源码链接)
java·spring ai·前端集成·mcp·mcp apps