Java Redis哈希案例如何读写

wen java案例 29

本文目录导读:

Java Redis哈希案例如何读写

  1. 使用Jedis操作Redis Hash
  2. 使用Spring Data Redis操作Redis Hash
  3. 实际应用场景示例

下面我来详细介绍Java操作Redis哈希(Hash)的读写案例,包括Jedis和Spring Data Redis两种主流方式。

使用Jedis操作Redis Hash

添加依赖

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

完整案例代码

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashMap;
import java.util.Map;
public class RedisHashExample {
    private static JedisPool jedisPool;
    static {
        // 创建连接池配置
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10);
        poolConfig.setMaxIdle(5);
        poolConfig.setMinIdle(2);
        // 初始化连接池(默认localhost:6379)
        jedisPool = new JedisPool(poolConfig, "localhost", 6379, 2000, "your-password");
        // 如果没有密码:new JedisPool(poolConfig, "localhost", 6379);
    }
    public static void main(String[] args) {
        try (Jedis jedis = jedisPool.getResource()) {
            // ============ 哈希写入操作 ============
            String userKey = "user:1001";
            // 1. 单个字段写入
            jedis.hset(userKey, "name", "张三");
            jedis.hset(userKey, "age", "25");
            jedis.hset(userKey, "city", "北京");
            // 2. 批量写入
            Map<String, String> userMap = new HashMap<>();
            userMap.put("email", "zhangsan@example.com");
            userMap.put("phone", "13800138000");
            userMap.put("score", "95.5");
            jedis.hmset(userKey, userMap);
            // 3. 设置字段仅在不存在时生效
            jedis.hsetnx(userKey, "name", "李四"); // 不会生效,因为name已存在
            // ============ 哈希读取操作 ============
            // 1. 获取单个字段
            String name = jedis.hget(userKey, "name");
            System.out.println("姓名: " + name);
            // 2. 获取多个字段
            String[] fields = {"name", "age", "city"};
            java.util.List<String> values = jedis.hmget(userKey, fields);
            System.out.println("多个字段值: " + values);
            // 3. 获取所有字段和值
            Map<String, String> allFields = jedis.hgetAll(userKey);
            System.out.println("所有字段:");
            allFields.forEach((field, value) -> 
                System.out.println("  " + field + ": " + value)
            );
            // 4. 获取所有字段名
            java.util.Set<String> keys = jedis.hkeys(userKey);
            System.out.println("所有字段名: " + keys);
            // 5. 获取所有值
            java.util.List<String> allValues = jedis.hvals(userKey);
            System.out.println("所有值: " + allValues);
            // ============ 其他操作 ============
            // 判断字段是否存在
            boolean exists = jedis.hexists(userKey, "name");
            System.out.println("name字段是否存在: " + exists);
            // 获取哈希长度
            long length = jedis.hlen(userKey);
            System.out.println("哈希长度: " + length);
            // 获取所有字段值(按字段顺序返回)
            java.util.List<String> allValuesOrdered = jedis.hvals(userKey);
            System.out.println("所有字段值(无序): " + allValuesOrdered);
            // 字段自增(用于数值类型)
            jedis.hincrBy(userKey, "visitCount", 1);
            jedis.hincrByFloat(userKey, "score", 2.5);
            // 删除字段
            jedis.hdel(userKey, "phone", "email");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接池
            if (jedisPool != null) {
                jedisPool.close();
            }
        }
    }
}

使用Spring Data Redis操作Redis Hash

添加依赖

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

配置文件 (application.yml)

spring:
  redis:
    host: localhost
    port: 6379
    password: your-password
    timeout: 2000ms
    lettuce:
      pool:
        max-active: 10
        max-idle: 5
        min-idle: 2

Service实现类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Service
public class HashRedisService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    // 获取HashOperations
    private HashOperations<String, String, Object> getHashOps() {
        return redisTemplate.opsForHash();
    }
    /**
     * 写入单个字段
     */
    public void put(String key, String field, Object value) {
        getHashOps().put(key, field, value);
    }
    /**
     * 批量写入
     */
    public void putAll(String key, Map<String, Object> map) {
        getHashOps().putAll(key, map);
    }
    /**
     * 写入并设置过期时间
     */
    public void putWithExpire(String key, String field, Object value, long timeout, TimeUnit unit) {
        getHashOps().put(key, field, value);
        redisTemplate.expire(key, timeout, unit);
    }
    /**
     * 仅在字段不存在时写入
     */
    public Boolean putIfAbsent(String key, String field, Object value) {
        return getHashOps().putIfAbsent(key, field, value);
    }
    // ============ 读取操作 ============
    /**
     * 获取单个字段
     */
    public Object get(String key, String field) {
        return getHashOps().get(key, field);
    }
    /**
     * 获取多个字段
     */
    public List<Object> multiGet(String key, List<String> fields) {
        return getHashOps().multiGet(key, fields);
    }
    /**
     * 获取所有字段和值
     */
    public Map<String, Object> getAll(String key) {
        return getHashOps().entries(key);
    }
    /**
     * 获取所有字段名
     */
    public Set<String> getKeys(String key) {
        return getHashOps().keys(key);
    }
    /**
     * 获取所有值
     */
    public List<Object> getValues(String key) {
        return getHashOps().values(key);
    }
    // ============ 其他操作 ============
    /**
     * 判断字段是否存在
     */
    public Boolean hasField(String key, String field) {
        return getHashOps().hasKey(key, field);
    }
    /**
     * 获取哈希长度
     */
    public Long size(String key) {
        return getHashOps().size(key);
    }
    /**
     * 字段自增
     */
    public Long increment(String key, String field, long delta) {
        return getHashOps().increment(key, field, delta);
    }
    /**
     * 浮点数字段自增
     */
    public Double increment(String key, String field, double delta) {
        return getHashOps().increment(key, field, delta);
    }
    /**
     * 删除字段
     */
    public Long delete(String key, String... fields) {
        return getHashOps().delete(key, (Object[]) fields);
    }
}

使用示例

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@SpringBootTest
public class HashRedisTest {
    @Autowired
    private HashRedisService hashRedisService;
    @Test
    public void testHashOperations() {
        String userKey = "user:1001";
        // 写入操作
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("name", "张三");
        userInfo.put("age", 25);
        userInfo.put("city", "北京");
        userInfo.put("email", "zhangsan@example.com");
        hashRedisService.putAll(userKey, userInfo);
        hashRedisService.putWithExpire(userKey, "temp", "临时数据", 10, TimeUnit.MINUTES);
        // 读取操作
        String name = (String) hashRedisService.get(userKey, "name");
        System.out.println("姓名: " + name);
        // 批量读取
        List<Object> values = hashRedisService.multiGet(userKey, Arrays.asList("name", "age", "city"));
        System.out.println("批量读取: " + values);
        // 获取所有数据
        Map<String, Object> allData = hashRedisService.getAll(userKey);
        System.out.println("所有数据: " + allData);
        // 自增操作
        hashRedisService.increment(userKey, "visitCount", 1);
        Long visitCount = (Long) hashRedisService.get(userKey, "visitCount");
        System.out.println("访问次数: " + visitCount);
        // 判断存在
        boolean hasAge = hashRedisService.hasField(userKey, "age");
        System.out.println("是否有age字段: " + hasAge);
        // 删除字段
        hashRedisService.delete(userKey, "email", "temp");
        // 获取哈希大小
        Long size = hashRedisService.size(userKey);
        System.out.println("哈希大小: " + size);
    }
}

实际应用场景示例

用户会话管理

@Service
public class UserSessionService {
    @Autowired
    private HashRedisService hashRedisService;
    // 存储用户会话信息
    public void saveUserSession(String sessionId, UserSession session) {
        String key = "session:" + sessionId;
        Map<String, Object> sessionMap = new HashMap<>();
        sessionMap.put("userId", session.getUserId());
        sessionMap.put("username", session.getUsername());
        sessionMap.put("loginTime", session.getLoginTime());
        sessionMap.put("ip", session.getIp());
        hashRedisService.putWithExpire(key, "data", sessionMap, 30, TimeUnit.MINUTES);
        hashRedisService.put(key, "active", true);
    }
    // 更新会话中的某个字段
    public void updateLastAccessTime(String sessionId) {
        String key = "session:" + sessionId;
        hashRedisService.put(key, "lastAccessTime", System.currentTimeMillis());
        redisTemplate.expire(key, 30, TimeUnit.MINUTES); // 续期
    }
    // 获取用户信息
    public UserSession getSession(String sessionId) {
        String key = "session:" + sessionId;
        Map<String, Object> data = (Map<String, Object>) hashRedisService.get(key, "data");
        if (data == null) return null;
        UserSession session = new UserSession();
        session.setUserId((Long) data.get("userId"));
        session.setUsername((String) data.get("username"));
        session.setLoginTime((Long) data.get("loginTime"));
        session.setIp((String) data.get("ip"));
        return session;
    }
}

就是Java操作Redis哈希的完整案例,包含了Jedis和Spring Data Redis两种方式,以及实际应用场景,哈希类型非常适合存储对象数据,可以灵活地读写部分字段,比存储整个JSON字符串更加高效。

抱歉,评论功能暂时关闭!