SpringBoot集成redisson操作redis

时间:2025-03-22 08:59:37

一、配置

1.1 引入maven

<dependency>
    <groupId></groupId>
    <artifactId>redisson</artifactId>
    <version>3.17.0</version>
</dependency>

1.2 配置文件

=0
=
=3000
#sentinel/cluster/single
=single
#连接池配置
-idle=16
-idle=8
-active=8
-wait=3000
-timeout=3000
-timeout=3000
=10
#单机配置
=192.168.60.23:6379
#集群配置
-interval=1000
=
-mode=SLAVE
-attempts=3
-attempts=3
-connection-pool-size=64
-connection-pool-size=64
-interval=1500
#哨兵配置
=business-master
=
-onlyWrite=true
-max=3

1.3 配置文件读取

/**
 * @Description: 配置文件读取
 */

@ConfigurationProperties(prefix="", ignoreUnknownFields = false)
@Data
@ToString
public class RedisProperties {

    private int database;

    /**
     * 等待节点回复命令的时间。该时间从命令发送成功时开始计时
     */
    private int timeout;

    private String password;

    private String mode;


    /**
     * 池配置
     */
    private RedisPoolProperties pool;


    /**
     * 单机信息配置
     */
    private RedisSingleProperties single;


    /**
     * 集群 信息配置
     */
    private RedisClusterProperties cluster;

    /**
     * 哨兵配置
     *
     */
    private RedisSentinelProperties sentinel;
}

/**
 * @Description: redis 池配置
 */

@Data
@ToString
public class RedisPoolProperties {

    private int maxIdle;

    private int minIdle;

    private int maxActive;

    private int maxWait;

    private int connTimeout;

    private int soTimeout;

    /**
     * 池大小
     */
    private int size;

}

/**
 * @Description: 单节点配置
 */

@Data
@ToString
public class RedisSingleProperties {

    private String address;
}

/**
 * @Description: 集群配置
 */

@Data
@ToString
public class RedisClusterProperties {

    /**
     * 集群状态扫描间隔时间,单位是毫秒
     */
    private int scanInterval;

    /**
     * 集群节点
     */
    private String nodes;

    /**
     * 默认值: SLAVE(只在从服务节点里读取)设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。
     * MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取
     */
    private String readMode;

    /**
     * (从节点连接池大小) 默认值:64
     */
    private int slaveConnectionPoolSize;

    /**
     * 主节点连接池大小)默认值:64
     */
    private int masterConnectionPoolSize;

    /**
     * (命令失败重试次数) 默认值:3
     */
    private int retryAttempts;

    /**
     *命令重试发送时间间隔,单位:毫秒 默认值:1500
     */
    private int retryInterval;

    /**
     * 执行失败最大次数默认值:3
     */
    private int failedAttempts;
}

/**
 * @Description: 哨兵配置
 */

@Data
@ToString
public class RedisSentinelProperties {

    /**
     * 哨兵master 名称
     */
    private String master;

    /**
     * 哨兵节点
     */
    private String nodes;

    /**
     * 哨兵配置
     */
    private boolean masterOnlyWrite;

    /**
     *
     */
    private int failMax;

}

1.4 CacheConfiguration

import ;
import ;
import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;

/**
 * @Description:
 */

@Configuration
@EnableConfigurationProperties()
public class CacheConfiguration {

    @Autowired
    private RedisProperties redisProperties;

    @Configuration
    @ConditionalOnClass({})
    @ConditionalOnExpression("'${}'=='single' or '${}'=='cluster' or '${}'=='sentinel'")
    protected class RedissonSingleClientConfiguration {

        /**
         * 单机模式 redisson 客户端
         */

        @Bean
        @ConditionalOnProperty(name="", havingValue="single")
        public RedissonClient redissonSingle() {
            Config config = new Config();
            String node = ().getAddress();
            node = ("redis://") ? node : "redis://" + node;
            SingleServerConfig serverConfig = ()
                    .setAddress(node)
                    .setTimeout(().getConnTimeout())
                    .setConnectionPoolSize(().getSize())
                    .setConnectionMinimumIdleSize(().getMinIdle());
            if(!(())) {
                (());
            }
            return (config);
        }

        /**
         * 集群模式的 redisson 客户端
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "", havingValue = "cluster")
        public RedissonClient redissonCluster() {
            ("cluster redisProperties:" + ());

            Config config = new Config();
            String[] nodes = ().getNodes().split(",");
            List<String> newNodes = new ArrayList<>();
            (nodes).forEach((index) -> (
                ("redis://") ? index : "redis://" + index)
            );

            ClusterServersConfig serverConfig = ()
                    .addNodeAddress((new String[0])
                    ).setScanInterval(
                        ().getScanInterval()
                    ).setIdleConnectionTimeout(
                        ().getSoTimeout()
                    ).setConnectTimeout(
                        ().getConnTimeout()
                    ).setRetryAttempts(
                        ().getRetryAttempts()
                    ).setRetryInterval(
                        ().getRetryInterval()
                    ).setMasterConnectionPoolSize(
                            ().getMasterConnectionPoolSize()
                    ).setSlaveConnectionPoolSize(
                            ().getSlaveConnectionPoolSize()
                    ).setTimeout(
                            ()
                    );

            if (!(())) {
                (());
            }
            return (config);
        }


        /**  
         * 哨兵模式 redisson 客户端
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "", havingValue = "sentinel")
        public RedissonClient redissonSentinel() {
            ("sentinel redisProperties:" + ());
            Config config = new Config();
            String[] nodes = ().getNodes().split(",");
            List<String> newNodes = new ArrayList<>();
            (nodes).forEach((index) -> (
                ("redis://") ? index : "redis://" + index)
            );

            SentinelServersConfig serverConfig = ()
                    .addSentinelAddress((new String[0]))
                    .setMasterName(().getMaster())
                    .setReadMode()
                    .setTimeout(())
                    .setMasterConnectionPoolSize(().getSize())
                    .setSlaveConnectionPoolSize(().getSize());

            if (!(())) {
                (());
            }
            return (config);
        }
    }
}

二、Redisson工具类

import .*;
import ;
import ;

import ;
import ;

/**
 * @Description:
 */

@Component
public class RedisUtils {

    /**
     * 默认缓存时间
     */
    private static final Long DEFAULT_EXPIRED = 32000L;

    
    /**
     * 自动装配redisson client对象
     */
    @Resource
    private RedissonClient redissonClient;

    
    /**
     * 用于操作key
     * @return RKeys 对象
     */
    public RKeys getKeys() {
        return ();
    }
    
    
    /**
     * 移除缓存
     *
     * @param key
     */
    public void delete(String key) {
        (key).delete();
    }

    
    /**
     * 获取getBuckets 对象
     *
     * @return RBuckets 对象
     */
    public RBuckets getBuckets() {
        return ();
    }

    
    /**
     * 读取缓存中的字符串,永久有效
     *
     * @param key 缓存key
     * @return 字符串
     */
    public String getStr(String key) {
        RBucket<String> bucket = (key);
        return ();
    }

    
    /**
     * 缓存字符串
     *
     * @param key
     * @param value
     */
    public void setStr(String key, String value) {
        RBucket<String> bucket = (key);
        (value);
    }

    
    /**
     * 缓存带过期时间的字符串
     *
     * @param key     缓存key
     * @param value   缓存值
     * @param expired 缓存过期时间,long类型,必须传值
     */
    public void setStr(String key, String value, long expired) {
        RBucket<String> bucket = (key, );
        (value, expired <= 0L ? DEFAULT_EXPIRED : expired, );
    }

    
    /**
     * string 操作,如果不存在则写入缓存(string方式,不带有redisson的格式信息)
     *
     * @param key     缓存key
     * @param value   缓存值
     * @param expired 缓存过期时间
     */
    public Boolean setIfAbsent(String key, String value, long expired) {
        RBucket<String> bucket = (key, );
        return (value, expired <= 0L ? DEFAULT_EXPIRED : expired, );
    }

    
    /**
     * 如果不存在则写入缓存(string方式,不带有redisson的格式信息),永久保存
     *
     * @param key   缓存key
     * @param value 缓存值
     */
    public Boolean setIfAbsent(String key, String value) {
        RBucket<String> bucket = (key, );
        return (value);
    }

    
    /**
     * 判断缓存是否存在
     *
     * @param key
     * @return true 存在
     */
    public Boolean isExists(String key) {
        return (key).isExists();
    }

    
    /**
     * 获取RList对象
     *
     * @param key RList的key
     * @return RList对象
     */
    public <T> RList<T> getList(String key) {
        return (key);
    }

    
    /**
     * 获取RMapCache对象
     *
     * @param key
     * @return RMapCache对象
     */
    public <K, V> RMapCache<K, V> getMap(String key) {
        return (key);
    }

    
    /**
     * 获取RSET对象
     *
     * @param key
     * @return RSET对象
     */
    public <T> RSet<T> getSet(String key) {
        return (key);
    }

    
    /**
     * 获取RScoredSortedSet对象
     *
     * @param key
     * @param <T>
     * @return RScoredSortedSet对象
     */
    public <T> RScoredSortedSet<T> getScoredSortedSet(String key) {
        return (key);
    }
}

三、常用RKeys的API操作

每个Redisson对象实例都会有一个与之对应的Redis数据实例,可以通过调用getName方法来取得redis数据实例的名称(key),所有于Redis key相关的操作都归纳在RKeys这个接口里。

RKeys keys = ();
//获取所有key值
Iterable<String> allKeys = ();
//模糊查询所有包含关键字key的值
Iterable<String> foundedKeys = ("key");
//删除多个key值
long numOfDeletedKeys = ("obj1", "obj2", "obj3");
//模糊删除key值
long deletedKeysAmount = ("test?");
//随机获取key
String randomKey = ();
//查询当前有多少个key
long keysAmount = ();

具体demo

private void getKeys() {
    RKeys keys = ();
    Iterable<String> allKeys = ();
    StringBuilder sb = new StringBuilder();
    for (String key : allKeys) {
        sb = (key).append(",");
    }
    ("所有的key:{}", (0, () - 1));
    // 模糊查询以 map 打头的所有 key
    allKeys = ("map*");
    sb = new StringBuilder();
    for (String key : allKeys) {
        sb = (key).append(",");
    }
    ("模糊匹配到的key:{}", (0, () - 1));
}

其中,getKeysByPattern是基于redis的scan命令实现。

四、通用对象桶Object Bucket

Redisson的分布式RBucket Java对象是一种通用对象桶,可以用来存放任意类型的对象。除了同步接口外,还提供异步(Async)、反射式(Reactive)和RxJava2标准的接口。还可以通过RBuckets接口实现批量操作多个RBucket对象。

/**
 * String 数据类型
 */
private void strDemo() {
    (DEMO_STR, "Hello, String.");
    ("String 测试数据:{}", (DEMO_STR));
    ("myBucket", "myBucketIsXxx");
    RBuckets buckets = ();
    Map<String, String> foundBuckets = ("myBucket*");
    Map<String, Object> map = new HashMap<>();
    ("myBucket1", "value1");
    ("myBucket2", 30L);

    // 同时保存全部通用对象桶。
    (map);
    Map<String, String> loadedBuckets = ("myBucket1", "myBucket2", "myBucket3");
    ("跨桶String 测试数据:{}", loadedBuckets);
    ("myBucket3", 320L);
}

五、散列 Hash

基于Redisson的分布式映射结构的RMap Java对象实现了和接口,与HashMap不同的是,RMap 保持了元素的插入顺序。该对象的最大容量受Redis限制,最大元素数量是4294967295个。

/**
 * Hash类型
 */
private void hashDemo() {
    RMap<Object, Object> map = ("mapDemo");
    ("demoId1", "123");
    ("demoId100", "13000");
    Object demoId1Obj = ("demoId1");
    ("Hash 测试数据:{}", demoId1Obj);
}

六、集合 Set

基于Redisson的分布式Set结构的RSet Java对象实现了接口,通过元素的互相状态比较保证了每个元素的唯一性,该对象的最大容量受Redis限制,最大元素数量是4294967295个。

/**
 * Set 测试
 */
private void setDemo() {
    RSet<String> set = ("setKey");
    ("value777");
    ("Set 测试数据");
    Iterator<String> iterator = ();
    while (()) {
        String next = ();
        (next);
    }
}

七、列表 List

基于Redisson的分布式列表 List 结构的RList Java对象在实现了接口的同时,确保了元素插入时的顺序,该对象的最大容量受Redis限制,最大元素数量是4294967295个。

/**
 * List数据类型
 */
private void listDemo() {
    RList<String> list = ("listDemo");
    ("listValue1");
    ("listValue2");

    ("List 测试数据:{}", (1));
}

综合示例

将上述demo放入一个API中,快速测试:

import .slf4j.Slf4j;
import .*;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;

@Slf4j
@RestController
@RequestMapping(value = "/redisson", method = )
public class StudyRedissonController {

    @Resource
    private RedisUtils redisUtils;

    private static String DEMO_STR = "demoStr";

    @PostMapping("/learnRedisson")
    public void learnRedisson() {
        //三种数据结构使用示例
        strDemo();
        hashDemo();
        listDemo();
        setDemo();
        getKeys();
    }

    private void getKeys() {
        RKeys keys = ();
        Iterable<String> allKeys = ();
        StringBuilder sb = new StringBuilder();
        for (String key : allKeys) {
            sb = (key).append(",");
        }
        ("所有的key:{}", (0, () - 1));
        // 模糊查询以 map 打头的所有 key
        allKeys = ("map*");
        sb = new StringBuilder();
        for (String key : allKeys) {
            sb = (key).append(",");
        }
        ("模糊匹配到的key:{}", (0, () - 1));
    }
    /**
     * Hash类型
     */
    private void hashDemo() {
        RMap<Object, Object> map = ("mapDemo");
        ("demoId1", "123");
        ("demoId100", "13000");
        Object demoId1Obj = ("demoId1");
        ("Hash 测试数据:{}", demoId1Obj);
    }

    /**
     * String 数据类型
     */
    private void strDemo() {
        (DEMO_STR, "Hello, String.");
        ("String 测试数据:{}", (DEMO_STR));
        ("myBucket", "myBucketIsXxx");
        RBuckets buckets = ();
        Map<String, String> foundBuckets = ("myBucket*");
        Map<String, Object> map = new HashMap<>();
        ("myBucket1", "value1");
        ("myBucket2", 30L);

        // 同时保存全部通用对象桶。
        (map);
        Map<String, String> loadedBuckets = ("myBucket1", "myBucket2", "myBucket3");
        ("跨桶String 测试数据:{}", loadedBuckets);
        ("myBucket3", 320L);
    }

    /**
     * List数据类型
     */
    private void listDemo() {
        RList<String> list = ("listDemo");
        ("listValue1");
        ("listValue2");

        ("List 测试数据:{}", (1));
    }
    /**
     * Set 测试
     */
    private void setDemo() {
        RSet<String> set = ("setKey");
        ("value777");
        ("Set 测试数据");
        Iterator<String> iterator = ();
        while (()) {
            String next = ();
            (next);
        }
    }

}