redis 操作类 redisService

本文介绍了一个基于Spring Boot的Redis服务类实现,包括缓存的增删查改、分布式锁的获取与释放等功能,并展示了如何利用RedisTemplate进行各种数据类型的CRUD操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {
    @Autowired
    private RedisTemplate redisTemplate;
    public static final String UNLOCK_LUA;
    private ThreadLocal<String> lockFlag = new ThreadLocal<String>();

    static {
        StringBuilder sb = new StringBuilder();
        sb.append("if      redis.call(\"get\",KEYS[1])      ==      ARGV[1]      ");
        sb.append("then      ");
        sb.append("     return      redis.call(\"del\",KEYS[1])      ");
        sb.append("else      ");
        sb.append("     return      0      ");
        sb.append("end      ");
        UNLOCK_LUA = sb.toString();
    }

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存设置时效时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public void remove(final String key) {
        redisTemplate.delete(key);
    }

    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    public boolean exists(String key, String value) {
        if (redisTemplate.hasKey(key)) {
            Object keyValue = get(key);
            if (null != keyValue && keyValue.toString().equals(value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    public String getStr(final String key) {
        Object result = get(key);
        return null == result ? null : result.toString();
    }

    //获取分布式锁
    private boolean lock(String key, long expire) {
        try {
            Object result = redisTemplate.execute(new RedisCallback<String>() {
                @Override
                public String doInRedis(RedisConnection connection) throws DataAccessException {
                    JedisCommands commands = (JedisCommands) connection.getNativeConnection();
                    String uuid = UUID.randomUUID().toString();
                    lockFlag.set(uuid);
                    return commands.set(key, uuid, "NX", "PX", expire);
                }
            });
            return !StringUtils.isEmpty(result);
        } catch (Exception e) {
        }
        return false;
    }

    //释放分布式锁
    public boolean unLock(String key) {
        //   释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
        try {
            List<String> keys = new ArrayList<String>();
            keys.add(key);
            List<String> args = new ArrayList<String>();
            args.add(lockFlag.get());
            //   使用lua脚本删除redis中匹配value的key,可以避免由于方法执行时间过长而redis锁自动过期失效的时候误删其他线程的锁
            //   spring自带的执行脚本方法中,集群模式直接抛出不支持执行脚本的异常,所以只能拿到原redis的connection来执行脚本
            Long result = (Long) redisTemplate.execute(new RedisCallback<Long>() {
                public Long doInRedis(RedisConnection connection) throws DataAccessException {
                    Object nativeConnection = connection.getNativeConnection();
                    //   集群模式和单机模式虽然执行脚本的方法一样,但是没有共同的接口,所以只能分开执行
                    //   集群模式
                    if (nativeConnection instanceof JedisCluster) {
                        return (Long) ((JedisCluster) nativeConnection).eval(UNLOCK_LUA, keys, args);
                    }
                    //   单机模式
                    else if (nativeConnection instanceof Jedis) {
                        return (Long) ((Jedis) nativeConnection).eval(UNLOCK_LUA, keys, args);
                    }
                    return 0L;
                }
            });
            return result != null && result > 0;
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 哈希 添加
     *
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    /**
     * 哈希获取数据
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    /**
     * 列表添加
     *
     * @param k
     * @param v
     */
    public void lPush(String k, Object v) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    /**
     * 列表获取
     *
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k, l, l1);
    }

    /**
     * 集合添加
     *
     * @param key
     * @param value
     */
    public void add(String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    /**
     * 集合获取
     *
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     *
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    /**
     * 有序集合获取
     *
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}
### Spring Boot Redis 操作教程 在 Spring Boot 中集成并操作 Redis 是一种常见的需求,主要用于缓存、会话管理以及分布式锁等功能。以下是关于如何配置和使用 Redis 的详细说明。 #### 配置环境 为了使 Spring Boot 能够与 Redis 进行交互,需要完成以下准备工作: 1. **创建 Spring Boot 项目** 使用 Spring Initializr 或者手动创建一个 Spring Boot 项目,在构建工具中引入必要的依赖项。 2. **Maven 依赖** 下面是一个典型的 Maven `pom.xml` 文件中的依赖部分[^2]: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 如果需要支持 JSON 序列化 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ``` 3. **application.properties/yml 配置文件** 在项目的资源目录下编辑 `application.properties` 或 `application.yml` 文件来设置 Redis 的连接参数: ```properties spring.redis.host=localhost spring.redis.port=6379 spring.redis.password= spring.redis.database=0 ``` #### 编写代码示例 下面是一些基本的操作示例,展示如何通过 Java 代码与 Redis 进行交互。 ##### 1. 注入 RedisTemplate `RedisTemplate` 是 Spring 提供的一个用于操作 Redis 的模板。可以通过注入它来进行键值存储和其他复杂的数据结构操作。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @Service public class RedisService { @Autowired private RedisTemplate<String, Object> redisTemplate; public void setValue(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object getValue(String key) { return redisTemplate.opsForValue().get(key); } } ``` ##### 2. 存储和获取字符串型的值 这是最简单的用法之一,适用于普通的键值对场景。 ```java // 设置值 redisService.setValue("name", "Alice"); // 获取值 Object name = redisService.getValue("name"); System.out.println(name); // 输出 Alice ``` ##### 3. 处理更复杂的对象 如果要保存自定义的对象到 Redis,则可能需要用到序列化机制。推荐的方式是采用 Jackson 来处理 JSON 格式的转换。 假设有一个实体如下所示: ```java import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class User { private String id; private String username; private int age; } ``` 那么可以这样存储该对象至 Redis 并读取回来: ```java User user = new User(); user.setId("u1"); user.setUsername("Bob"); user.setAge(28); // 将对象存入 Redis redisService.setValue("user:u1", user); // 从 Redis 取回对象 User fetchedUser = (User) redisService.getValue("user:u1"); System.out.println(fetchedUser.getUsername()); // 输出 Bob ``` #### 增强功能:迁移至 Redisson 对于更高阶的需求,比如分布式锁或者集群模式下的高性能数据访问,可以选择迁移到 Redisson 工具库。其提供了更为丰富的 API 支持[^1]。 例如初始化 Redisson 客户端实例的过程大致如下: ```java Config config = new Config(); config.useSingleServer() .setAddress("redis://127.0.0.1:6379") .setTimeout(3000); RLock lock = redissonClient.getLock("myDistributedLock"); lock.lock(); // 加锁逻辑... try { // 执行业务逻辑 } finally { lock.unlock(); // 解锁逻辑... } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值