SpringBoot整合Redis使用注解进行缓存方式

 更新时间:2025年03月05日 09:43:20   作者:fkjavaer  
文章介绍了使用Redis进行数据缓存的几种方式,包括手动配置RedisTemplate、使用Spring的Caching模块以及配置自定义的RedisCacheManager

Hello,各位小伙伴,最近项目中需要将一些常用的数据缓存起来,毫无疑问,我们采用了Redis来缓存数据。那么使用Redis缓存数据有哪些方式呢?接下来我会一一道来。

1.环境搭建

引入Redis依赖以及Spring相关的依赖

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

2.使用RedisTemplate

使用RedisTemplate调用API时,我们通常需要去配置key,value的序列化器,以及创建一个RedisUtils类来完成缓存的增删改查以及过期时间的设置。

配置如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        // 设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());

        template.afterPropertiesSet();
        return template;
    }
}

RedisUtils:

public class RedisUtils {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     */

    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     */

    public void set(String key, Object value, long time) {
        if (time > 0) {
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        } else {
            set(key, value);
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     */
    public void hset(String key, String item, Object value) {
        redisTemplate.opsForHash().put(key, item, value);
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     */
    public void hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
        redisTemplate.opsForHash().put(key, item, value);
        if (time > 0) {
            expire(key, time, timeUnit);
        }
    }

    /**
     * @param key 键
     * @param map 多个field-value
     */
    public void hmset(String key, Map<String, Object> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * @param key      键
     * @param map      多个field-value
     * @param time     过期时间
     * @param timeUnit 时间单位
     */
    public void hmset(String key, Map<String, Object> map, long time, TimeUnit timeUnit) {
        redisTemplate.opsForHash().putAll(key, map);
        if (time > 0) {
            expire(key, time, timeUnit);
        }
    }

    /**
     * @param key  键
     * @param item Field
     * @return 获得的值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * @param key 键
     * @return hash表中key对应的map
     */
    public Map<Object, Object> hEntries(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * @param key   键
     * @param value 值
     */
    public void sadd(String key, Object value) {
        redisTemplate.opsForSet().add(key, value);
    }

    /**
     * @param key      键
     * @param value    值
     * @param time     过期时间
     * @param timeUnit 时间单位
     */
    public void sadd(String key, Object value, long time, TimeUnit timeUnit) {
        redisTemplate.opsForSet().add(key, value);
        if (time > 0) {
            expire(key, time, timeUnit);
        }
    }

    /**
     * @param key 键
     * @return 数据
     */
    public Set<Object> smembers(String key) {
        return redisTemplate.opsForSet().members(key);

    }

    public void expire(String key, long time, TimeUnit timeUnit) {
        if (time > 0) {
            redisTemplate.expire(key, time, timeUnit);
        }
    }

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

通过以上的配置,我们在使用缓存的时候,直接调用API就可以进行操作了。但是有个问题就是,我们在缓存一些常用数据的时候,通常我们需要先判断一下缓存中有没有该key,如果没有我们再去数据库中查询出来,并缓存。

这样的话我们需要去做一些判断的操作,缓存中有就去缓存中取,没有就从数据库中取出来并缓存。那么有没有更方便的操作方式呢,答案当然是有的。

3.使用@EnableCaching+@Cacheable

Spring为我们提供了Caching模块,我们可以该模块给我们提供的功能,使用注解很方便完成数据缓存

在使用的过程中,我发现,虽然我们配置了RedisTemplate的序列化,但是对于基于注解的Redis缓存来说是无效的,我们需要配置自定义的RedisCacheManager

配置如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        // 设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());

        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }
}

使用方法:

  1. 在启动类上加上@EnableCaching
  2. 在需要缓存数据的方法上加上@Cacheable(cacheNames = "xxx"),方法的返回值就是我们需要缓存的数据
  3. 基于以上的操作,我们就可以很方便的将需要缓存的数据缓存到Redis

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis使用resultMap获取不到值的解决方案

    mybatis使用resultMap获取不到值的解决方案

    这篇文章主要介绍了mybatis使用resultMap获取不到值的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • JVM的GC日志及运行参数解读

    JVM的GC日志及运行参数解读

    这篇文章主要为大家介绍了JVM的GC日志及运行参数解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • MyBatis批量插入的几种方式效率比较

    MyBatis批量插入的几种方式效率比较

    最近工作中遇到了解析excel,然后批量插入,发现这个插入时间比较长,所以想要进行一些优化,下面这篇文章主要给大家介绍了关于MyBatis批量插入的几种方式效率比较的相关资料,需要的朋友可以参考下
    2021-09-09
  • springboot启动时没有日志的原因分析

    springboot启动时没有日志的原因分析

    这篇文章主要介绍了springboot启动时没有日志的原因分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java通过客户端访问服务器webservice的方法

    java通过客户端访问服务器webservice的方法

    这篇文章主要介绍了java通过客户端访问服务器webservice的方法,涉及java创建与调用webservice的相关技巧,需要的朋友可以参考下
    2016-08-08
  • SpringBoot之QueryDsl嵌套子查询问题

    SpringBoot之QueryDsl嵌套子查询问题

    这篇文章主要介绍了SpringBoot之QueryDsl嵌套子查询问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 使用java生成字母验证码

    使用java生成字母验证码

    这篇文章主要介绍了使用java生成字母验证码的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 浅谈Spring自定义注解从入门到精通

    浅谈Spring自定义注解从入门到精通

    这篇文章主要介绍了浅谈Spring自定义注解从入门到精通,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 深入浅析hbase的优点

    深入浅析hbase的优点

    本文讲述了HBase的特征和它的优点,并简要回顾了行键设计的重点之处,它还向你展示了如何在本地配置HBase环境,使用命令创建表、插入数据、检索指定行以及最后如何进行scan操作,感兴趣的朋友一起看看吧
    2017-09-09
  • 如何使用Spring AOP的通知类型及创建通知

    如何使用Spring AOP的通知类型及创建通知

    这篇文章主要给大家介绍了关于如何使用Spring AOP的通知类型及创建通知的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring AOP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12

最新评论