SpringBoot整合Redis详细教程

系列文章目录

(一)Redis(windows+Linux)安装及入门教程 - 掘金 (juejin.cn)

(二)Redis中的五大数据类型 - 掘金 (juejin.cn)

(三)Redis中的三种特殊类型 - 掘金 (juejin.cn)


前言

本文先介绍了 Redis 官方首选的 Java 客户端开发包Jedis(Java操作Redis的原生API),然后进行了SpringBoot对Redis的整合,自定义了RedisTemplate,以及封装了一个RedisUtils,如果只需要看SpringBoot整合Redis可以直接跳至第二小节,如果喜欢本文的话可以收藏+点赞+关注φ(゜▽゜*)♪


一、使用Jedis🥩

什么是Jedis

Jedis是一个Java实现的Redis客户端连接工具。它允许Java开发者通过Java代码轻松地与Redis数据库进行交互。

Jedis提供了与Redis交互的多种方法,这些方法与在Redis命令行中的命令基本相同,但添加了一些额外的便捷方法。

相较于Redisson,Jedis更接近于原生的Redis操作,而Redisson则更适用于分布式应用,提供了分布式锁以及其他多种数据结构。

测试

创建一个Maven工程

引入依赖

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

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.7</version>
</dependency>

编码测试

  1. 连接数据库

    java 复制代码
    package com;
    
    import redis.clients.jedis.Jedis;
    
    public class TestPing {
        public static void main(String[] args) {
            //new Jedis对象
            Jedis jedis = new Jedis("127.0.0.1", 6379);
            //jedis中有redis中的所有命令
            System.out.println(jedis.ping());
        }
    }
  2. 常用API(所有函数与命令相同)

    java 复制代码
    package com;
    
    import redis.clients.jedis.Jedis;
    
    public class TestPing {
        public static void main(String[] args) {
            //new Jedis对象
            Jedis jedis = new Jedis("127.0.0.1", 6379);
            //jedis中有redis中的所有命令
            System.out.println("清空当前数据库" + jedis.flushDB());//flushall,是删除所有数据库中的key
            System.out.println("判断某个键是否存在" + jedis.exists("username"));
            System.out.println("新增键值对" + jedis.set("username", "keye"));
            System.out.println("新增键值对" + jedis.set("test", "test"));
            System.out.println("获取键值对" + jedis.get("username"));
            System.out.println("获取所有键" + jedis.keys("*"));
            System.out.println("删除键值对" + jedis.del("username"));
            System.out.println("获取键存储的值类型" + jedis.type("test"));
            System.out.println("重命名key" + jedis.rename("test", "new_test"));
            System.out.println("切换数据库" + jedis.select(1));
            System.out.println("查看当前数据库中key的数量" + jedis.dbSize());
            jedis.close();
        }
    }

Jedis事务操作

java 复制代码
package com;

import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

/**
 * @Author YZK
 * @Date 2023/9/23
 */
public class TestTx {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("username", "kkkk");
        jsonObject.put("password", "123456");
        //开启事务
        Transaction multi = jedis.multi();
        try {
            multi.set("user", jsonObject.toJSONString());
            multi.exec(); //执行事务
        } catch (Exception e) {
            multi.discard(); //放弃事务
            throw new RuntimeException(e);
        } finally {
            System.out.println(jedis.get("user"));
            jedis.close(); //关闭连接
        }
    }
}

二、SpringBoot整合Redis🥓

创建SpringBoot工程

SpringBoot在2.x之后的版本,将Jeris替换成了lettuce

由于Jedis 是直连模式,在多个线程间共享一个 Jedis 实例时是线程不安全的,每个线程都去拿自己的 Jedis 实例,当连接数量增多时,物理连接成本就较高了。

Lettuce的连接是基于Netty的,连接实例可以在多个线程间共享,一个多线程的应用可以使用同一个连接实例,而不用担心并发线程的数量。通过异步的方式可以让我们更好地利用系统资源。

源码分析

RedisAutoConfiguration中

java 复制代码
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(RedisConnectionDetails.class)
	PropertiesRedisConnectionDetails redisConnectionDetails(RedisProperties properties) {
		return new PropertiesRedisConnectionDetails(properties);
	}

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate") //可以自定义一个redisTemplate来替换默认的
	@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    //默认的RedisTemplate没有过多的设置,redis对象需要序列化
    //两个泛型都是Object类型,过后需要强转<String,Object>
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    //由于String类型是redis中最常使用的类型,所以单独抽出了一个Bean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
		return new StringRedisTemplate(redisConnectionFactory);
	}

}

RedisTemplate中

序列化配置

默认序列化方式

测试

配置文件

properties 复制代码
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379

测试

java 复制代码
@SpringBootTest
class RedisSpringbootApplicationTests {
    @Resource
    RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        //opsForList()操作list
        //opsForValue()操作String
        redisTemplate.opsForList().rightPush("list", "value");
        redisTemplate.opsForValue().set("key", "value");
    }
}

保存对象(需要序列化)

java 复制代码
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
    private String name;
    private int age;
}
java 复制代码
@SpringBootTest
class RedisSpringbootApplicationTests {
    @Resource
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() throws JsonProcessingException {
        //真实开发都是使用JSON来传递对象
        User user = new User("kkk", 32);
        //此行代码省略的前提是User对象实现Serializable接口,否则会报错
        String jsonUser = new ObjectMapper().writeValueAsString(user);
        redisTemplate.opsForValue().set("user", jsonUser);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }

}

自定义RedisTemplate

java 复制代码
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplateSelf(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
        genericJackson2JsonRedisSerializer.serialize(om);
        //String序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key、hash的key 采用 String序列化方式
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        // value、hash的value 采用 Jackson 序列化方式
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

代码解释:

  1. 使用@Configuration注解表示这是一个配置类。
  2. 定义了一个名为redisTemplateSelf (避免歧义) 的Bean,它是一个泛型为String和Object的RedisTemplate实例。
  3. 在redisTemplate方法中,首先创建一个RedisTemplate实例,并设置其连接工厂为传入的redisConnectionFactory。
  4. 创建一个GenericJackson2JsonRedisSerializer实例,用于将Java对象序列化为JSON格式,以便存储在Redis中。
  5. 创建一个ObjectMapper实例,用于处理JSON数据的序列化和反序列化。设置其可见性为ALL,以便序列化所有属性;激活默认类型检查,以便在序列化时添加类型信息。
  6. 将genericJackson2JsonRedisSerializer应用于ObjectMapper实例。
  7. 创建一个StringRedisSerializer实例,用于将字符串类型的key和hash的key序列化为Redis中的字符串。
  8. 设置RedisTemplate的key序列化器和hash key序列化器为stringRedisSerializer。
  9. 设置RedisTemplate的value序列化器和hash value序列化器为genericJackson2JsonRedisSerializer,以便将Java对象序列化为JSON格式并存储在Redis中。
  10. 调用template.afterPropertiesSet()方法,完成配置。
  11. 返回配置好的RedisTemplate实例。

查看RedisSerializer接口查看序列化实现方式

测试使用自定义的RedisTemplate

java 复制代码
@SpringBootTest
class RedisSpringbootApplicationTests {
    
    @Autowired
    @Qualifier(value = "redisTemplateSelf")
    private RedisTemplate redisTemplate;
    
    @Test
    void contextLoads() throws JsonProcessingException {
        User user = new User("kkk", 32);
        redisTemplate.opsForValue().set("user", user);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }
}

未自定义RedisTemplate

使用了自定义RedisTemplate

封装RedisTemplate

封装RedisTemplate是为了简化原生API的操作,此处代码较长,直接复制使用即可

java 复制代码
package com.redis.utils;

import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtils {

    @Resource(name = "redisTemplateSelf")
    private RedisTemplate<String, Object> redisTemplate;
    // =============================common============================

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     */
    public boolean expire(String key, long time) {
        try {
            if (time >= 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }


    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return Optional.ofNullable(redisTemplate.getExpire(key, TimeUnit.SECONDS)).orElse(0L);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return Optional.ofNullable(redisTemplate.hasKey(key)).orElse(false);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 删除缓存
     *
     * @param keys 可以传一个值 或多个
     */
    public boolean del(List<String> keys) {
        if (!keys.isEmpty()) {
            final Long aLong = Optional.ofNullable(redisTemplate.delete(keys)).orElse(0L);
            return aLong > 0;
        }
        return false;
    }

    // ============================String=============================

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return Optional.ofNullable(redisTemplate.opsForValue().increment(key, delta)).orElse(0L);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return Optional.ofNullable(redisTemplate.opsForValue().increment(key, -delta)).orElse(0L);
    }

    public long decr(String key) {
        return Optional.ofNullable(redisTemplate.opsForValue().increment(key)).orElse(0L);
    }

    // ================================hash=================================

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hKeys(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 获取hashKey的长度
     *
     * @param key 键
     * @return 哈桑Key的大小
     */
    public Long hlen(String key) {
        Long size = 0L;
        try {
            size = Optional.of(redisTemplate.opsForHash()).map(o -> o.size(key)).orElse(0L);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
        return size;
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 向一张hash表中放入多条数据,如果不存在将创建
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    // ===============================list=================================


    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     */
    public Object lGet(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list指定范围的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     */
    public List<Object> lRange(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     */
    public long lLen(String key) {
        try {
            return Optional.ofNullable(redisTemplate.opsForList().size(key)).orElse(0L);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     */
    public boolean lUpdate(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            return Optional.ofNullable(redisTemplate.opsForList().remove(key, count, value)).orElse(0L);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    // ============================set=============================

    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     */
    public Set<Object> sMember(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sIsMember(String key, Object value) {
        return Optional.ofNullable(redisTemplate.opsForSet().isMember(key, value)).orElse(false);
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sAdd(String key, Object... values) {
        return Optional.ofNullable(redisTemplate.opsForSet().add(key, values)).orElse(0L);
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetWithTime(String key, long time, Object... values) {
        try {
            if (time > 0) {
                expire(key, time);
            }
            return Optional.ofNullable(redisTemplate.opsForSet().add(key, values)).orElse(0L);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 随机移除并返回一个元素
     *
     * @param key 键
     * @return 被移除的元素
     */
    public Object sPop(String key) {
        return redisTemplate.opsForSet().pop(key);
    }

    /**
     * 随机返回指定长度的count个元素
     *
     * @param key   键
     * @param count 返回元素的个数
     * @return 返回的元素
     */
    public List<Object> sRandMember(String key, long count) {
        return redisTemplate.opsForSet().randomMembers(key, count);
    }

    /**
     * 两个set集合求交集
     *
     * @param key1 其中一个set的key
     * @param key2 另一个set的key
     * @return 两个set的差集
     */
    public Set<Object> sDiff(String key1, String key2) {
        return redisTemplate.opsForSet().difference(key1, key2);
    }

    /**
     * 两个set集合求交集
     *
     * @param key1 其中一个set的key
     * @param key2 另一个set的key
     * @return 两个set的交集
     */
    public Set<Object> Sinter(String key1, String key2) {
        return redisTemplate.opsForSet().intersect(key1, key2);
    }

    /**
     * 两个set集合求并集
     *
     * @param key1 其中一个set的key
     * @param key2 另一个set的key
     * @return 两个set的并集
     */
    public Set<Object> sUnion(String key1, String key2) {
        return redisTemplate.opsForSet().union(key1, key2);
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     */
    public long sGetSetSize(String key) {
        return Optional.ofNullable(redisTemplate.opsForSet().size(key)).orElse(0L);
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        return Optional.ofNullable(redisTemplate.opsForSet().remove(key, values)).orElse(0L);
    }

    // ============================sorted set=============================

    /**
     * 添加元素到zSet集合当中去
     *
     * @param key   键
     * @param value 值
     * @param score 分数
     * @return 是否添加成功
     */
    public boolean zAdd(String key, Object value, double score) {
        return Optional.ofNullable(redisTemplate.opsForZSet().add(key, value, score)).orElse(false);
    }

    /**
     * 返回指定分数范围的数据
     *
     * @param key   键
     * @param start 起始位置
     * @param end   结束位置
     * @return 指定分数范围内的zSet
     */
    public Set<Object> zRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }
}

测试RedisUtils

java 复制代码
@SpringBootTest
class RedisSpringbootApplicationTests {

    @Resource
    RedisUtils redisUtils;

    @Test
    void contextLoads()  {
        User user = new User("kkk", 32);
//        redisTemplate.opsForValue().set("user", user);
        redisUtils.set("user", user);
//        System.out.println(redisTemplate.opsForValue().get("user"));
        System.out.println(redisUtils.get("user"));
    }

}
//运行结果 User(name=kkk, age=32)

参考资料

狂神说JavaRedis最新超详细版教程通俗易懂_哔哩哔哩_bilibili

springboot整合jedis (lettuce)_jedis 转 lettuce_高大王竟然被注册的博客-CSDN博客

基于RedisTemplate封装的工具类_redistemplate 包装为 工具类_花开不识君的博客-CSDN博客

相关推荐
我是苏苏5 小时前
Redis开发07:使用stackexchange.redis库实现简单消息队列
数据库·redis·缓存
梦飞翔2386 小时前
Spring Boot
spring boot
青柠编程7 小时前
基于Spring Boot的选课管理系统架构设计
java·spring boot·后端
Mr.wangh7 小时前
Redis主从复制
java·数据库·redis
前端橙一陈7 小时前
LocalStorage Token vs HttpOnly Cookie 认证方案
前端·spring boot
每次的天空9 小时前
Android -Glide实战技术总结
java·spring boot·spring
码事漫谈10 小时前
C++内存泄漏排查:从基础到高级的完整工具指南
后端
王嘉俊92510 小时前
ThinkPHP 入门:快速构建 PHP Web 应用的强大框架
开发语言·前端·后端·php·框架·thinkphp
码事漫谈10 小时前
C++多线程数据竞争:从检测到修复的完整指南
后端
Code blocks11 小时前
SpringBoot快速生成二维码
java·spring boot·后端