胖胖的枫叶
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
  • 标签索引
  • 2024年

    • 配置Mac环境
    • 业务知识会计管理
    • 业务知识会计基础
    • 业务知识什么是财务
  • 2023年

    • 项目 Boi
  • 2022年

    • 企业架构故障管理
    • 企业架构开发债务
  • 2021年

    • Python3.8 Matplotlib员工数据分析
    • Python3.8 Matplotlib IP折线图
    • Python3.8 词云 IP地址
    • Redis RediSearch
    • Rust第一个CLI程序
    • Rust所有权
    • Rust函数与控制流
    • Rust变量与数据类型
    • Rust入门
    • 企业架构分布式系统
    • 编程式权限设计
    • Java JVM优化
    • SpringBoot MyBatis 批量
    • SpringBoot 测试Mock
    • SpringBoot Redis布隆过滤器
    • CentOS7 Jenkins 部署
    • SpringBoot WebClient
    • Docker Drone 部署
    • SpringBoot MyBatis
    • SpringBoot Redisson
    • SpringBoot MyBatis 雪花算法
    • Java Netty
    • Redis 扫描
    • CentOS7 Jenkins本地部署分级
    • Mac 安装 Neo4j Jupyter
    • Mac OpenJDK11 JavaFX 环境
    • Mac 安装 Jenv
    • SpringBoot Redis 延时队列
    • SpringBoot MDC日志
    • SpringBoot 定时任务
    • CentOS7 Nginx GoAccess
    • SpringBoot MyBatis 分析
    • SpringBoot Lucene
    • 企业架构分布式锁
    • 学习技巧减少学习排斥心理
    • SpringBoot 动态数据源
    • Docker Compose SpringBoot MySQL Redis
    • SpringBoot 阻塞队列
    • Docker Compose Redis 哨兵
    • Docker Compose Redis 主从
    • 网络通信
  • 2020年

    • SpringBoot 延时队列
    • MySQL基础(四)
    • Java 雪花算法
    • Redis Geo
    • 网络通信 Tcpdump
    • Spring SPI
    • Java Zookeeper
    • SpringBoot JMH
    • 网络通信 Wireshark
    • Docker Compose Redis MySQL
    • CentOS7 Docker 部署
    • Netty 源码环境搭建
    • MySQL基础(三)
    • CentOS7 Selenium运行环境
    • CentOS7 Nginx HTTPS
    • Java JMH
    • SpringBoot 修改Tomcat版本
    • Java Eureka 钉钉通知
    • SpringBoot 错误钉钉通知
    • Java JVM
    • Git 合并提交
    • CentOS7 OpenResty 部署
  • 2019年

    • Redis CLI
    • CentOS7 Nginx 日志
    • 编程式代码风格
    • IDEA 插件
    • Skywalking 源码环境搭建
    • SpringBoot Redis 超时错误
    • 编程式 gRPC
    • Java Arthas
    • Docker Compose Redis 缓存击穿
    • Docker ElasticSearch5.6.8 部署
    • Docker Mysql5.7 部署
    • Spring Redis 字符串
    • Docker Zookeeper 部署
    • Docker Redis 部署
    • SpringBoot Dubbo
    • CentOS7 CMake 部署
    • 应用程序性能指标
    • Java Code 递归
    • CentOS7 ELK 部署
    • CentOS7 Sonarqube 部署
    • Java Selenium
    • Java JJWT JUnit4
    • Spring 源码环境搭建
    • Java JUnit4
    • Java Web JSON Token
    • 编程式 FastDFS
    • Java XPath
    • Redis基础(二)
    • Redis基础(一)
    • Java MyBatis JUnit4
    • Java MyBatis H2 JUnit4
    • MyBatis 源码环境搭建
    • Git 配置
    • Java 核心
    • Java Dubbo
    • Java JavaCollecionsFramework
    • Java Maven
    • Java MyBatis
    • Java Spring
    • Java SpringMVC
    • MySQL
    • Redis
  • 2018年

    • Java HashMap
    • Java HashSet
    • Java Code 交换值
    • Spring Upgrade SpringBoot
    • Mac 编程环境
    • Java Log4j
    • 网络通信 Modbus
    • MySQL基础(二)
    • MySQL基础(一)
    • Java Stack
    • Java Vector
    • CentOS7 RabbitMQ 部署
    • CentOS7 Redis 部署
    • CentOS7 MongoDB 部署
    • CentOS7 基础命令
    • Java Eureka Zookeeper
    • CentOS7 MySQL 部署
    • Git 分支
    • CentOS7 Java环境配置
    • Java LinkedList
    • Java ArrayList
    • Spring Annotation Aop

Spring Redis 字符串

本章是整理知识内容,为强化知识长期更新。

spring-redis-string

Spring-data-redis 有两个客户端,本章节主要使用lettuce来作为代码演示。尽可能面向redis编程。

  • 参考文献redis-string

代码实现

  • 接口
package cn.z201.learning.redis.operating.service;


import java.util.HashMap;
import java.util.List;

/**
 * @author z201.coding@gmail.com
 * @see cn.z201.learning.redis.operating.service.impl.RedisStringImpl
 **/
public interface RedisStringI {

    /**
     * 将字符串值 value 关联到 key 。
     * 如果 key 已经持有其他值, SET 就覆写旧值, 无视类型。
     * 当 SET 命令对一个带有生存时间(TTL)的键进行设置之后, 该键原有的 TTL 将被清除。
     * {@link = http://redisdoc.com/string/set.html }
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param value
     * @return
     */
    Boolean set(String key, String value);

    /**
     * 只在键 key 不存在的情况下, 将键 key 的值设置为 value 。
     * 若键 key 已经存在, 则 SETNX 命令不做任何动作。
     * SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     * {@link = http://redisdoc.com/string/setnx.html  }
     *
     * @param key
     * @param value
     * @return
     */
    Boolean setNx(String key, String value);

    /**
     * 将键 key 的值设置为 value , 并将键 key 的生存时间设置为 seconds 秒钟。
     * 如果键 key 已经存在, 那么 SETEX 命令将覆盖已有的值。
     * <p>
     * {@link = http://redisdoc.com/string/setex.html}
     * 可用版本: >= 2.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param timeout seconds 秒
     * @param value
     * @return
     */
    Boolean setEx(String key, Long timeout, String value);

    /**
     * 这个命令和 SETEX 命令相似, 但它以毫秒为单位设置 key 的生存时间, 而不是像 SETEX 命令那样以秒为单位进行设置。
     * <p>
     * {@link = http://redisdoc.com/string/psetex.html}
     * 可用版本: >= 2.6.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param timeout milliseconds
     * @param value
     * @return
     */
    Boolean pSetEx(String key, Long timeout, String value);

    /**
     * 返回与键 key 相关联的字符串值。
     * {@link = http://redisdoc.com/string/get.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @return
     */
    Object get(String key);

    /**
     * 获取key设置的value,并返回之前设置的值。
     * {@link = http://redisdoc.com/string/getset.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param value
     * @return
     */
    Object getSet(String key, String value);

    /**
     * 返回key对应value的长度
     * {@link = http://redisdoc.com/string/strlen.html}
     * 可用版本: >= 2.2.0
     * 复杂度: O(1)
     *
     * @param key
     * @return
     */
    Long strLen(String key);

    /**
     * 如果键 key 已经存在并且它的值是一个字符串, APPEND 命令将把 value 追加到键 key 现有值的末尾。
     * 如果 key 不存在, APPEND 就简单地将键 key 的值设为 value , 就像执行 SET key value 一样。
     * {@link = http://redisdoc.com/string/append.html}
     * 可用版本: >= 2.0.0
     * 时间复杂度: 平摊O(1)
     *
     * @param key
     * @param value
     * @return
     */
    Long appEnd(String key, String value);

    /**
     * 从偏移量 offset 开始, 用 value 参数覆写(overwrite)键 key 储存的字符串值。
     * 不存在的键 key 当作空白字符串处理。
     * SETRANGE 命令会确保字符串足够长以便将 value 设置到指定的偏移量上,
     * 如果键 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,
     * 但你设置的 offset 是 10 ), 那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )进行填充。
     * <p>
     * {@link = http://redisdoc.com/string/setrange.html}
     * 可用版本: >= 2.2.0
     * 时间复杂度:对于长度较短的字符串,命令的平摊复杂度O(1);对于长度较大的字符串,命令的复杂度为 O(M) ,其中 M 为 value 的长度。
     *
     * @param key
     * @param offset
     * @param value
     * @return
     */
    Boolean setRange(String key, Long offset, String value);


    /**
     * 返回键 key 储存的字符串值的指定部分, 字符串的截取范围由 start 和 end 两个偏移量决定 (包括 start 和 end 在内)。
     * 负数偏移量表示从字符串的末尾开始计数, -1 表示最后一个字符, -2 表示倒数第二个字符, 以此类推。
     * GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。
     * <p>
     * {@link = http://redisdoc.com/string/setrange.html}
     * 可用版本: >= 2.4.0
     * 时间复杂度: O(N),其中 N 为被返回的字符串的长度。
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    Object getRange(String key, Long start, Long end);

    /**
     * 为键 key 储存的数字值加上一。
     * 如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令。
     * 如果键 key 储存的值不能被解释为数字, 那么 INCR 命令将返回一个错误。
     * 本操作的值限制在 64 位(bit)有符号数字表示之内。
     * <p>
     * {@link = http://redisdoc.com/string/incr.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @return
     */
    Long incr(String key);

    /**
     * 为键 key 储存的数字值加上增量 increment 。
     * 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 INCRBY 命令。
     * 如果键 key 储存的值不能被解释为数字, 那么 INCRBY 命令将返回一个错误。
     * 本操作的值限制在 64 位(bit)有符号数字表示之内。
     * <p>
     * {@link = http://redisdoc.com/string/incrby.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param sum
     * @return
     */
    Long incrBy(String key, Long sum);

    /**
     * 为键 key 储存的值加上浮点数增量 increment 。
     * 如果键 key 不存在, 那么 INCRBYFLOAT 会先将键 key 的值设为 0 , 然后再执行加法操作。
     * 如果命令执行成功, 那么键 key 的值会被更新为执行加法计算之后的新值, 并且新值会以字符串的形式返回给调用者。
     * 无论是键 key 的值还是增量 increment , 都可以使用像 2.0e7 、 3e5 、 90e-2 那样的指数符号(exponential notation)来表示, 但是,
     * 执行 INCRBYFLOAT 命令之后的值总是以同样的形式储存, 也即是, 它们总是由一个数字,
     * 一个(可选的)小数点和一个任意长度的小数部分组成(比如 3.14 、 69.768 ,诸如此类), 小数部分尾随的 0 会被移除,
     * 如果可能的话, 命令还会将浮点数转换为整数(比如 3.0 会被保存成 3 )。
     * 此外, 无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 命令的计算结果最多只保留小数点的后十七位。
     * 当以下任意一个条件发生时, 命令返回一个错误:
     * 键 key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型);
     * 键 key 当前的值或者给定的增量 increment 不能被解释(parse)为双精度浮点数。
     * <p>
     * {@link = http://redisdoc.com/string/incrbyfloat.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param sum
     * @return
     */
    Float incrByFloat(String key, Float sum);

    /**
     * 为键 key 储存的数字值减去一。
     * 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 DECR 操作。
     * 如果键 key 储存的值不能被解释为数字, 那么 DECR 命令将返回一个错误。
     * 本操作的值限制在 64 位(bit)有符号数字表示之内。
     * <p>
     * {@link = http://redisdoc.com/string/decr.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @return
     */
    Long decr(String key);

    /**
     * 将键 key 储存的整数值减去减量 decrement 。
     * 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 DECRBY 命令。
     * 如果键 key 储存的值不能被解释为数字, 那么 DECRBY 命令将返回一个错误。
     * 本操作的值限制在 64 位(bit)有符号数字表示之内。
     * <p>
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(1)
     *
     * @param key
     * @param sum
     * @return
     */
    Long decrBy(String key, Long sum);

    /**
     * 同时为多个键设置值。
     * 如果某个给定键已经存在, 那么 MSET 将使用新值去覆盖旧值,
     * 如果这不是你所希望的效果, 请考虑使用 MSETNX 命令, 这个命令只会在所有给定键都不存在的情况下进行设置。
     * MSET 是一个原子性(atomic)操作, 所有给定键都会在同一时间内被设置, 不会出现某些键被设置了但是另一些键没有被设置的情况。
     * {@link = http://redisdoc.com/string/mset.html}
     * 可用版本: >= 1.0.1
     * 时间复杂度: O(N),其中 N 为被设置的键数量。
     *
     * @param map
     * @return
     */
    Boolean mSet(HashMap<String, Object> map);

    /**
     * 当且仅当所有给定键都不存在时, 为所有给定键设置值。
     * 即使只有一个给定键已经存在, MSETNX 命令也会拒绝执行对所有键的设置操作。
     * MSETNX 是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置, 不可能出现第三种状态。
     * {@link = http://redisdoc.com/string/msetnx.html}
     * 可用版本: >= 1.0.1
     * 时间复杂度: O(N), 其中 N 为被设置的键数量。
     *
     * @param map
     * @return
     */
    Boolean mSetNx(HashMap<String, Object> map);

    /**
     * 返回给定的一个或多个字符串键的值。
     * 如果给定的字符串键里面, 有某个键不存在, 那么这个键的值将以特殊值 nil 表示。
     * {@link = http://redisdoc.com/string/mget.html}
     * 可用版本: >= 1.0.0
     * 时间复杂度: O(N) ,其中 N 为给定键的数量。
     *
     * @param key
     * @return
     */
    List<Object> mGet(String[] key);

}

  • 代码实现
package cn.z201.learning.redis.operating.service.impl;

import cn.z201.learning.redis.operating.Tools;
import cn.z201.learning.redis.operating.service.RedisStringExpansionI;
import cn.z201.learning.redis.operating.service.RedisStringI;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author z201.coding@gmail.com
 **/
@Slf4j
@Service
public class RedisStringImpl implements RedisStringI {

   @Autowired
    RedisTemplate redisTemplate;

    @Override
    public Boolean set(String key, String value) {
        Tools.notNull(key, value);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.set(stringRedisSerializer.serialize(key),
                    stringRedisSerializer.serialize(value));
        });
    }

    @Override
    public Boolean setNx(String key, String value) {
        Tools.notNull(key, value);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.setNX(stringRedisSerializer.serialize(key),
                    stringRedisSerializer.serialize(value));
        });
    }

    @Override
    public Boolean setEx(String key, Long timeout, String value) {
        Tools.notNull(key, value);
        Tools.notNull(timeout);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.setEx(stringRedisSerializer.serialize(key),
                    timeout,
                    stringRedisSerializer.serialize(value));
        });
    }

    @Override
    public Boolean pSetEx(String key, Long timeout, String value) {
        Tools.notNull(key, value);
        Tools.notNull(timeout);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.pSetEx(stringRedisSerializer.serialize(key),
                    timeout,
                    stringRedisSerializer.serialize(value));
        });
    }


    @Override
    public Object get(String key) {
        Tools.notNull(key);
        return redisTemplate.execute((RedisCallback<Object>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            byte[] bytes = connection.get(stringRedisSerializer.serialize(key));
            if (null != bytes || bytes.length != 0) {
                return stringRedisSerializer.deserialize(bytes);
            }
            return null;
        });
    }

    @Override
    public Object getSet(String key, String value) {
        Tools.notNull(key, value);
        return redisTemplate.execute((RedisCallback<Object>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            byte[] bytes = connection.getSet(stringRedisSerializer.serialize(key)
                    , stringRedisSerializer.serialize(value));
            if (null != bytes || bytes.length != 0) {
                return stringRedisSerializer.deserialize(bytes);
            }
            return null;
        });
    }

    @Override
    public Long strLen(String key) {
        Tools.notNull(key);
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.strLen(stringRedisSerializer.serialize(key));
        });
    }

    @Override
    public Long appEnd(String key, String value) {
        Tools.notNull(key, value);
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.append(stringRedisSerializer.serialize(key),
                    stringRedisSerializer.serialize(value));
        });
    }

    @Override
    public Boolean setRange(String key, Long offset, String value) {
        Tools.notNull(key, value);
        Tools.notNull(offset);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            connection.setRange(stringRedisSerializer.serialize(key),
                    stringRedisSerializer.serialize(value),
                    offset);
            return true;
        });
    }

    @Override
    public Object getRange(String key, Long start, Long end) {
        Tools.notNull(key);
        Tools.notNull(start);
        Tools.notNull(end);
        return redisTemplate.execute((RedisCallback<Object>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            byte[] bytes = connection.getRange(stringRedisSerializer.serialize(key),
                    start,
                    end);
            return stringRedisSerializer.deserialize(bytes);
        });
    }

    @Override
    public Long incr(String key) {
        Tools.notNull(key);
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.incr(stringRedisSerializer.serialize(key));
        });
    }

    @Override
    public Boolean batchIncr(String[] key) {
        Tools.notNull(key);
        return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            connection.openPipeline();
            Integer length = key.length;
            for (int i = 0; i < length; i++) {
                connection.incr(stringRedisSerializer.serialize(key[i]));
            }
            List<Object> result = connection.closePipeline();
            if (null == result || result.isEmpty() || result.contains(false)) {
                return false;
            }
            return true;
        });
    }

    @Override
    public Long incrBy(String key, Long sum) {
        Tools.notNull(key);
        if (null == sum || sum < 0) {
            throw new RuntimeException();
        }
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.incrBy(stringRedisSerializer.serialize(key), sum);
        });
    }

    @Override
    public Double incrByFloat(String key, Double sum) {
        Tools.notNull(key);
        if (null == sum || sum < 0) {
            throw new RuntimeException();
        }
        return (Double) redisTemplate.execute((RedisCallback<Double>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.incrBy(stringRedisSerializer.serialize(key), sum.doubleValue());
        });
    }

    @Override
    public Long decr(String key) {
        Tools.notNull(key);
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.decr(stringRedisSerializer.serialize(key));
        });
    }

    @Override
    public Long decrBy(String key, Long sum) {
        Tools.notNull(key);
        return (Long) redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            return connection.decrBy(stringRedisSerializer.serialize(key), sum);
        });
    }

    @Override
    public Boolean mSet(HashMap<String, Object> map) {
        return mSetNx(map, false);
    }

    @Override
    public Boolean mSetNx(HashMap<String, Object> map) {
        return mSetNx(map, true);
    }

    @Override
    public List<Object> mGet(String[] key) {
        Tools.notNull(key);
        return (List<Object>) redisTemplate.execute((RedisCallback<List<Object>>) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            Integer length = key.length;
            byte[][] bytes = new byte[length][];
            for (int i = 0; i < length; i++) {
                bytes[i] = stringRedisSerializer.serialize(key[i]);
            }
            List<byte[]> list = connection.mGet(bytes);
            if (null != list || list.size() == 0) {
                List<Object> result = new ArrayList<>();
                length = list.size();
                for (int i = 0; i < length; i++) {
                    Object object = stringRedisSerializer.deserialize(list.get(i));
                    result.add(String.valueOf(object));
                }
                return result;
            }
            return null;
        });
    }

    /**
     * 重构之后的代码
     * @param map
     * @param nx
     * @return
     */
    private Boolean mSetNx(HashMap<String, Object> map, Boolean nx) {
        Assert.notNull(map, "map is null");
        Assert.notEmpty(map, "map is empty");
        redisTemplate.execute((RedisCallback) connection -> {
            RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();
            connection.openPipeline();
            Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
            String key;
            Object value;
            Map<byte[], byte[]> tuple = new HashMap<>();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                key = entry.getKey();
                value = entry.getValue();
                Tools.notNull(key, value.toString());
                tuple.put(stringRedisSerializer.serialize(key), stringRedisSerializer.serialize(value));
            }
            if (nx) {
                if (!tuple.isEmpty()) {
                    return connection.mSetNX(tuple);
                }
            } else {
                if (!tuple.isEmpty()) {
                    return connection.mSet(tuple);
                }
            }
            return false;
        });
        return true;
    }
}

  • 单元测试
    @Test
    public void testRedisString() {
        Assert.assertEquals(true, redisString.set("key", "value"));
        Assert.assertEquals("value", redisString.get("key"));
        HashMap map = new HashMap<String, Object>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        Assert.assertEquals(true, redisString.mSet(map));
        Assert.assertEquals(true, redisString.set("key3", "1"));
        Assert.assertEquals(true, redisString.set("key4", "1"));
        log.info("key3  key4 {}", redisString.mGet(new String[]{"key3", "key4"}));
        log.info("key4 incr {} ", redisString.incr("key4"));
        log.info("key4 3 incrBy {} ", redisString.incrBy("key4", 3L));
        log.info("key4 decr {} ", redisString.decr("key4"));
        log.info("key4 2 incrBy {} ", redisString.incrBy("key4", 2L));
        Set<String> keys = redisTool.keys("key*");
        keys.forEach(item -> log.info(" keys -> key {} : value {} ", item, redisString.get(item)));
        redisString.setEx("key1111", 10L, "value");
    }
  • 日志输出
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests - key4 incr 2 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests - key3  key4 [1, 2]
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests - key4 decr 1 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests - key4 incrBy 4 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests -  keys -> key key4 : value 4 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests -  keys -> key key1 : value value1 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests -  keys -> key key3 : value 1 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests -  keys -> key key : value value 
[main] INFO  c.z.l.r.o.RedisOperatingApplicationTests -  keys -> key key2 : value value2 

END

最近更新: 2025/12/27 18:51
Contributors: 庆峰
Prev
Docker Mysql5.7 部署
Next
Docker Zookeeper 部署