返回顶部
首页 > 资讯 > 精选 >springboot中如何使用redis
  • 603
分享到

springboot中如何使用redis

springbootredis 2023-05-30 21:05:57 603人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关SpringBoot中如何使用redis,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。正文很多时候,我们会在springboot中配置Redis,但是就那么几个配置就配好了,没

这篇文章将为大家详细讲解有关SpringBoot中如何使用redis,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

正文

很多时候,我们会在springboot中配置Redis,但是就那么几个配置就配好了,没办法知道为什么,这里就详细的讲解一下
这里假设已经成功创建了一个springboot项目

redis连接工厂类

第一步,需要加上springboot的redis jar

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

然后我们写一个配置类,创建了一个redis连接的工厂的spring bean。(Redis连接工厂会生成到Redis数据库服务器的连接)

@Configurationpublic class RedisConfig {  @Bean  public RedisConnectionFactory redisCF(){    //如果什么参数都不设置,默认连接本地6379端口    JedisConnectionFactory factory = new JedisConnectionFactory();    factory.setPort(6379);    factory.setHostName("localhost");    return factory;  }}

单元测试,看看这个工厂方法的使用

@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = Application.class)public class RedisTest {    @Autowired  RedisConnectionFactory factory;      @Test  public void testRedis(){    //得到一个连接    RedisConnection conn = factory.getConnection();    conn.set("hello".getBytes(), "world".getBytes());    System.out.println(new String(conn.get("hello".getBytes())));  }}

输出结果 :world,说明已经成功获取到连接,并且往redis获取添加数据,

template(模版)

但是我们发现每次添加的key和value都是byte数组类型(使用很麻烦),于是spring为我们带来了redis template(模版)

Spring Data Redis提供了两个模板:
  RedisTemplate
  StringRedisTemplate

首先我们先创建一个RedisTemplate模板类,类型的key是String类型,value是Object类型(如果key和value都是String类型,建议使用StringRedisTemplate)

  @Bean  public RedisTemplate redisTemplate(RedisConnectionFactory factory){    //创建一个模板类    RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();    //将刚才的redis连接工厂设置到模板类中    template.setConnectionFactory(factory);    return template;  }

单元测试

@Autowired    RedisTemplate<String, Object> template;    @Test  public void testRedisTemplate(){    template.opsForValue().set("key1", "value1");    System.out.println(template.opsForValue().get("key1"));  }

得到结果输出value1,是不是很方便了呢。

 如果是操作集合呢,也很方便的哈。

  @Test  public void testRedisTemplateList(){      Pruduct prud = new Pruduct(1, "洗发水", "100ml");    Pruduct prud2 = new Pruduct(2, "洗面奶", "200ml");    //依次从尾部添加元素    template.opsForList().rightPush("pruduct", prud);    template.opsForList().rightPush("pruduct", prud);    //查询索引0到商品总数-1索引(也就是查出所有的商品)    List<Object> prodList = template.opsForList().range("pruduct", 0,template.opsForList().size("pruduct")-1);    for(Object obj:prodList){      System.out.println((Pruduct)obj);    }    System.out.println("产品数量:"+template.opsForList().size("pruduct"));      }

key和value序列化

当保存一条数据的时候,key和value都要被序列化成JSON数据,取出来的时候被序列化成对象,key和value都会使用序列化器进行序列化,spring data redis提供多个序列化器

GenericToStringSerializer:使用Spring转换服务进行序列化;
JacksonjsonRedisSerializer:使用Jackson 1,将对象序列化为JSON;
Jackson2JsonRedisSerializer:使用Jackson 2,将对象序列化为JSON;
jdkSerializationRedisSerializer:使用Java序列化;
OxmSerializer:使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实现序列化,用于XML序列化;
StringRedisSerializer:序列化String类型的key和value。

RedisTemplate会默认使用JdkSerializationRedisSerializer,这意味着key和value都会通过Java进行序列化。StringRedisTemplate默认会使用StringRedisSerializer

例如,假设当使用RedisTemplate的时候,我们希望将Product类型的value序列化为JSON,而key是String类型。RedisTemplate的seTKEySerializer()和setValueSerializer()方法就需要如下所示:

@Bean  public RedisTemplate redisTemplate(RedisConnectionFactory factory) {    // 创建一个模板类    RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();    // 将刚才的redis连接工厂设置到模板类中    template.setConnectionFactory(factory);    // 设置key的序列化器    template.setKeySerializer(new StringRedisSerializer());    // 设置value的序列化器    //使用Jackson 2,将对象序列化为JSON    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);    //json转对象类,不设置默认的会将json转成HashMap    ObjectMapper om = new ObjectMapper();    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    jackson2JsonRedisSerializer.setObjectMapper(om);    template.setValueSerializer(jackson2JsonRedisSerializer);    return template;  }

到这里,大家肯定会对springboot使用redis有了简单的了解。

springboot缓存某个方法

申明缓存管理器

在某些时候,我们可能有这样的需求,用户登录的时候,我们会从数据库中读取用户所有的权限,部门等信息。而且每次刷新页面都需要判断该用户有没有这个权限,如果不停的从数据库中读并且计算,是非常耗性能的,所以我们这个时候就要用到了springboot为我们带来的缓存管理器

首先在我们的RedisConfig这个类上加上@EnableCaching这个注解。

这个注解会被spring发现,并且会创建一个切面(aspect) 并触发Spring缓存注解的切点(pointcut) 。 根据所使用的注解以及缓存的状态, 这个切面会从缓存中获取数据, 将数据添加到缓存之中或者从缓存中移除某个值。 

接下来我们需要申明一个缓存管理器的bean,这个作用就是@EnableCaching这个切面在新增缓存或者删除缓存的时候会调用这个缓存管理器的方法

  @Bean  public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {    return new RedisCacheManager(redisTemplate);  }

 当然,缓存管理器除了RedisCacheManager还有一些其他的。例如

  • SimpleCacheManager

  • NoOpCacheManager

  • ConcurrentMapCacheManager

  • CompositeCacheManager

  • EhCacheCacheManager

ConcurrentMapCacheManager,这个简单的缓存管理器使用java.util.concurrent.ConcurrentHashMap作为其缓存存储。它非常简单,因此对于开发、测试或基础的应用来讲,这是一个很不错的选择.

添加缓存

接下来我们在controller层的方法内加上注解,然后启动我们的项目。

@RequestMapping("/getPrud")  @Cacheable("prudCache")  public Pruduct getPrud(@RequestParam(required=true)String id){    System.out.println("如果第二次没有走到这里说明缓存被添加了");    return pruductDao.getPrud(Integer.parseInt(id));  }

发现打印的这段话只被打印一次,说明在走到这个方法的时候触发了一个切面,并且查找返回缓存中的数据。

当然@Cacheable注解也可以放到这个dao层的方法里面,但是这里会报一个错,Integer无法转成String,因为我们dao层方法的参数类型是int,而RedisTemplate的key类型是String,这里是要注意的。

打开redis的客户端发现redis对应的key就是我们的参数1,这个时候就会出问题,比如说我在其他要缓存的方法的参数也是1,就会重复。后面我们会将自定义这个key的值。

除了@Cacheable添加缓存外,springboot还为我们带了了其他几个注解

springboot中如何使用redis

删除缓存

在delete的时候用@CacheEvict清楚这条缓存。

  @RequestMapping("/deletePrud")  @CacheEvict("pruddeleteCache")  public String deletePrud(@RequestParam(required=true)String id){    return "SUCCESS";  }

@CachePut将这个方法的返回值放到缓存,如果我们放一个Pruduct对象,他会将这个对象作为key,这显然不是我们想要的。这个时候就需要自定义我们的key。

自定义key

@Cacheable和@CachePut都有一个名为key属性,这个属性能够替换默认的key,它是通过一个表达式(Spel表达式,spring提供的,很简单)计算得到的。

例如下面的就是将返回对象的id当作key来存储(但是Pruduct的id是int类型,所以需要将数字转化成String类型)

  @RequestMapping("/savePrud")  @CachePut(value="prudsaveCache",key="#result.id +''")  public Pruduct savePrud(Pruduct prud){    return prud;  }

另外除了#result是代表函数的返回值,spring还为我们带来了其他的一些元数据

springboot中如何使用redis

 条件化缓存

通过为方法添加Spring的缓存注解,Spring就会围绕着这个方法创建一个缓存切面。但是,在有些场景下我们可能希望将缓存功能关闭。

@Cacheable和@CachePut提供了两个属性用以实现条件化缓存:unless和condition,这两个属性都接受一个SpEL表达式。如果unless属性的SpEL表达式计算结
果为true,那么缓存方法返回的数据就不会放到缓存中。与之类似,如果condition属性的SpEL表达式计算结果为false,那么对于这个方法缓存就会被禁用掉

表面上来看,unless和condition属性做的是相同的事情。但是,这里有一点细微的差别。

unless属性只能阻止将对象放进缓存,但是在这个方法调用的时候,依然会去缓存中进行查找,如果找到了匹配的值,就会返回找到的值。

与之不同,如果condition的表达式计算结果为false,那么在这个方法调用的过程中,缓存是被禁用的。就是说,不会去缓存进行查找,同时返回值也不会放进缓存中。

  @RequestMapping("/getPrud2")  @CachePut(value ="prudCache",unless="#result.desc.contains('nocache')")  public Pruduct getPrud2(@RequestParam(required=true)String id){    System.out.println("如果走到这里说明,说明缓存没有生效!");    Pruduct p = new Pruduct(Integer.parseInt(id), "name_nocache"+id, "nocache");    return p;  }

上面的代码中,如果返回的对象desc中包含nocache字符串,则不进行缓存。

总结demo:

将类名方法名和pruduct的id作为key

@RequestMapping("/getPrud3")  @Cacheable(value ="prudCache",key="#root.targetClass.getName() + #root.methodName + #id")  public Pruduct getPrud3(@RequestParam(required=true)String id){    System.out.println("如果第二次没有走到这里说明缓存被添加了");    return pruductDao.getPrud(Integer.parseInt(id));  }

最后注意

#result 方法返回值不能用在@Cacheable上,只能用在@CachePut

springboot配置升级简单化

当然上面的配置只是为了了解原理的哈,实际上我们使用会更简单点。我们重写了RedisConfig

@Configuration@EnableCaching//开启缓存public class RedisConfig extends CachinGConfigurerSupport {  @Bean  public KeyGenerator keyGenerator() {    return new KeyGenerator() {      @Override      public Object generate(Object target, Method method, Object... params) {        StringBuilder sb = new StringBuilder();        sb.append(target.getClass().getName());        sb.append(method.getName());        for (Object obj : params) {          sb.append(obj.toString());        }        return sb.toString();      }    };  }      @Bean  public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {    return new RedisCacheManager(redisTemplate);  }  @Bean  @Primary  public RedisTemplate redisTemplate(RedisConnectionFactory factory) {    // 创建一个模板类    RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();    // 将刚才的redis连接工厂设置到模板类中    template.setConnectionFactory(factory);    // 设置key的序列化器    template.setKeySerializer(new StringRedisSerializer());    // 设置value的序列化器    //使用Jackson 2,将对象序列化为JSON    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);    //json转对象类,不设置默认的会将json转成hashmap    ObjectMapper om = new ObjectMapper();    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    jackson2JsonRedisSerializer.setObjectMapper(om);    template.setValueSerializer(jackson2JsonRedisSerializer);    return template;  }}

然后在resources下的application.properties下配置

# REDIS (RedisProperties)# Redis数据库索引(默认为0)spring.redis.database=0 # Redis服务器地址spring.redis.host=127.0.0.1# Redis服务器连接端口spring.redis.port=6379 # Redis服务器连接密码(默认为空)spring.redis.passWord=# 连接池最大连接数(使用负值表示没有限制)spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制)spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接spring.redis.pool.min-idle=0 # 连接超时时间(毫秒)spring.redis.timeout=0

大家发现我们并没有注册RedisConnectionFactory,那是因为spring默认帮我们读取application.properties文件并且注册了一个factorybean

keyGenerator方法帮我们注册了一个key的生成规则,就不用我们写spel表达式了,根据反射的原理读取类名+方法名+参数。但是我们有时候还是需要结合spel的。

然后在controller上加上@Cacheable("cachename"),之后就可以在redis看到保存了并且key的值是keyGenerator生成的名字

关于“springboot中如何使用redis”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: springboot中如何使用redis

本文链接: https://lsjlt.com/news/221464.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • springboot中如何使用redis
    这篇文章将为大家详细讲解有关springboot中如何使用redis,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。正文很多时候,我们会在springboot中配置redis,但是就那么几个配置就配好了,没...
    99+
    2023-05-30
    springboot redis
  • SpringBoot集成如何使用Redis
    小编给大家分享一下SpringBoot集成如何使用Redis,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!SpringBoot集成使用redisJedis 是 Redis 官方推出的一款面向 Java 的客户端,提供了很多...
    99+
    2023-06-29
  • SpringBoot中如何使用Redis作为全局锁
    这篇文章主要讲解了“SpringBoot中如何使用Redis作为全局锁”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot中如何使用Redis作为全局锁”吧!一、模拟没有锁情况...
    99+
    2023-06-29
  • SpringBoot集成Redis如何使用RedisRepositories
    这篇“SpringBoot集成Redis如何使用RedisRepositories”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这...
    99+
    2023-06-29
  • 详解SpringBoot如何使用Redis和Redis缓存
    目录一、配置环境二、Redis的基本操作三、使用redis作缓存一、配置环境 首先,先创建一个SpringBoot项目,并且导入Redis依赖,使用Jedis进行连接测试。 本人的R...
    99+
    2024-04-02
  • 如何在SpringBoot项目中使用redis数据库
    今天就跟大家聊聊有关如何在SpringBoot项目中使用redis数据库,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。REmote DIctionary Server(Redis) ...
    99+
    2023-06-07
  • 使用SpringBoot中整合Redis
    目录SpringBoot中整合RedisSpringBoot整合Redis改不了database问题SpringBoot中整合Redis 本次,我们以IDEA + SpringBoo...
    99+
    2024-04-02
  • springboot中redis怎么使用
    在Spring Boot中使用Redis,可以使用以下步骤:1. 添加依赖:在`pom.xml`文件中添加Redis的依赖:```x...
    99+
    2023-09-04
    springboot redis
  • springboot中如何使用redis和分布式session共享
    这篇文章主要介绍了springboot中如何使用redis和分布式session共享,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。对于分布式使用Nginx+Tomcat实现负...
    99+
    2023-05-30
    springboot redis session
  • SpringBoot中如何整合Lettuce redis
    这篇文章主要介绍“SpringBoot中如何整合Lettuce redis”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot中如何整合Lettuce redis”文章能帮助大家解决问...
    99+
    2023-06-08
  • springboot 如何使用jedis连接Redis数据库
    springboot 使用jedis连接Redis数据库 1. 在 pom.xml 配置文件中添加依赖 <!-- redis 依赖 --> <...
    99+
    2024-04-02
  • 如何使用SpringBoot + Redis实现接口限流
    本篇内容介绍了“如何使用SpringBoot + Redis实现接口限流”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!配...
    99+
    2023-06-30
  • SpringBoot中如何使用Aop
    这篇文章将为大家详细讲解有关SpringBoot中如何使用Aop,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。什么是aopAOP(Aspect OrientedProgramming):面向...
    99+
    2023-06-20
  • SpringBoot中如何使用Servlet
    今天小编给大家分享一下SpringBoot中如何使用Servlet的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.方式一(...
    99+
    2023-07-02
  • redis中zset如何使用
    这篇文章将为大家详细讲解有关redis中zset如何使用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redis中zset是set的一个升级版本,他在set的基础上增加了...
    99+
    2024-04-02
  • Bump中如何使用Redis
    这篇文章将为大家详细讲解有关Bump中如何使用Redis,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  Bump的Redis怎么用  1.将Redis用作...
    99+
    2024-04-02
  • redis中如何使用scan
    这篇文章主要为大家展示了“redis中如何使用scan”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“redis中如何使用scan”这篇文章吧。 ...
    99+
    2024-04-02
  • ThinkPHP5中如何使用redis
    目录配置redis使用string(字符串)Hash(哈希)List(列表)Set(集合)zset(有序集合)总结前提:因为本文主要围绕着在thinkPHP5中使用redis的,所以...
    99+
    2023-05-14
    ThinkPHP5使用redis ThinkPHP5 redis
  • Node.js中如何使用Redis
    这篇文章主要介绍了Node.js中如何使用Redis的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Node.js中如何使用Redis文章都会有所收获,下面我们一起来看看吧。1. 认识redis对于前端的小伙伴来...
    99+
    2023-07-04
  • SpringBoot之如何使用Redis实现分布式锁
    小编给大家分享一下SpringBoot之如何使用Redis实现分布式锁,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!springboot是什么springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作