欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

程序员文章站 2022-03-07 15:39:12
0、前言 在项目中,缓存作为一种高效的提升性能的手段,几乎必不可少,Redis作为其中的佼佼者被广泛应用; 一、spring boot集成Redis 1、添加依赖 2、配置文件增加Redis配置 3、使用 这样就集成进来了,就可以使用了,有两种template可以直接使用,RedisTemplate ......

0、前言

  在项目中,缓存作为一种高效的提升性能的手段,几乎必不可少,redis作为其中的佼佼者被广泛应用;

一、spring boot集成redis

1、添加依赖

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-data-redis</artifactid>
        </dependency>

2、配置文件增加redis配置

####### redis ################
#第几个数据库,由于redis中数据库不止一个(默认会开启15个)
spring.redis.database=1
# 也可指定为127.0.0.1
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=88888888

# springboot2.x以上如此配置,由于2.x的客户端是lettuce
# 单位要带上
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=10000ms
spring.redis.lettuce.shutdown-timeout=100ms

# springboot1.x如此配置,由于1.x的客户端是jedis
#spring.redis.jedis.pool.max-active=8
#spring.redis.jedis.pool.min-idle=0
#spring.redis.jedis.pool.max-idle=8
#spring.redis.jedis.pool.max-wait=-1
#spring.redis.timeout=500

3、使用

  这样就集成进来了,就可以使用了,有两种template可以直接使用,redistemplate和stringredistemplate有opsforvalue、opsforlist、opsforset、opsforzset、opsforhash几种访问方法,简单示例如下:

   @resource
    private redistemplate redistemplate; 

   // 写入缓存
   redistemplate.opsforvalue().set("111","anson");

    //读取缓存
   string str = redistemplate.opsforvalue().get("111").tostring();

运行后可以查看到缓存中已经写入,读取也正常读取出来

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 

4、总结:

  可以看到,写入redis的是经过转码的,不方便查看,一般我们在使用的时候,会替换掉它默认的解析器,并且将相关操作封装成工具类方便使用;通常redis我们是作为缓存服务器来使用,实际项目中,缓存有两种方式,一种是手动的方式:就是像上面的方式,将redis的解析器替换,然后封装工具类;在使用的地方,先判断缓存中时候有需要的数据,没有的换就从数据库中去取,然后写入redis缓存,有的话就直接从redis缓存取;手动的方式虽然有时候更灵活,但是每个方法都需要写一堆代码,很累赘,基本上我们是不会用这种方式的,所以上面的方式只是简单介绍,什么封装工具类啊那些都没贴代码出来,想用这种方式的自己去百度,一大堆;

  缓存的第二种方式就是配合注解实现缓存,方便,只需要在需要缓存的方法上加上注解即可,实际项目中,基本都是使用这种方式,下面介绍

二、@cacheable注解实现redis缓存

1、添加依赖

<!--4、集成redis -->
        <dependency>
            <groupid>org.apache.commons</groupid>
            <artifactid>commons-pool2</artifactid>
            <version>2.4.2</version>
        </dependency>
        <!-- redis依赖,2.0以上使用这个依赖 -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-data-redis</artifactid>
        </dependency>
        <!-- 缓存依赖 -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-cache</artifactid>
        </dependency>

2、配置文件中增加配置

####### redis ################
#第几个数据库,由于redis中数据库不止一个
spring.redis.database=1
# 也可指定为127.0.0.1
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=88888888

# springboot2.x以上如此配置,由于2.x的客户端是lettuce
# 单位要带上
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=10000ms
spring.redis.lettuce.shutdown-timeout=100ms

# springboot1.x如此配置,由于1.x的客户端是jedis
#spring.redis.jedis.pool.max-active=8
#spring.redis.jedis.pool.min-idle=0
#spring.redis.jedis.pool.max-idle=8
#spring.redis.jedis.pool.max-wait=-1
#spring.redis.timeout=500

3、实现自定义缓存管理器

package com.anson.config;


import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.cache.annotation.cachingconfigurersupport;
import org.springframework.cache.annotation.enablecaching;
import org.springframework.cache.interceptor.keygenerator;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.data.redis.cache.rediscacheconfiguration;
import org.springframework.data.redis.cache.rediscachemanager;
import org.springframework.data.redis.connection.redisconnectionfactory;
import org.springframework.data.redis.serializer.*;

import java.time.duration;

/**
 * @description: redis缓存配置类
 * @author: anson
 * @date: 2019/12/8 21:34
 */

@configuration
@enablecaching
public class rediscacheconfig extends cachingconfigurersupport {

    private static final logger logger = loggerfactory.getlogger(rediscacheconfig.class);

    // 自定义key生成器
    @bean
    public keygenerator keygenerator(){
        return (o, method, params) ->{
            stringbuilder sb = new stringbuilder();
            sb.append(o.getclass().getname()); // 类目
            sb.append(method.getname()); // 方法名
            for(object param: params){
                sb.append(param.tostring()); // 参数名
            }
            return sb.tostring();
        };
    }

    // 配置缓存管理器
    @bean
    public rediscachemanager cachemanager(redisconnectionfactory connectionfactory) {
        rediscacheconfiguration config = rediscacheconfiguration.defaultcacheconfig()
                .entryttl(duration.ofseconds(60000000)) // 60s缓存失效
                // 设置key的序列化方式
                .serializekeyswith(redisserializationcontext.serializationpair.fromserializer(keyserializer()))
                // 设置value的序列化方式
                .serializevalueswith(redisserializationcontext.serializationpair.fromserializer(valueserializer()))
                // 不缓存null值
                .disablecachingnullvalues();

        rediscachemanager rediscachemanager = rediscachemanager.builder(connectionfactory)
                .cachedefaults(config)
                .transactionaware()
                .build();

        logger.info("自定义rediscachemanager加载完成");
        return rediscachemanager;
    }


    // key键序列化方式
    private redisserializer<string> keyserializer() {
        return new stringredisserializer();
    }

    // value值序列化方式
    private genericjackson2jsonredisserializer valueserializer(){
        return new genericjackson2jsonredisserializer();
       // return  new genericfastjsonredisserializer();
    }
}

4、使用:可以直接使用了,在userserviceimpl中

    @override
    @cacheable(cachenames = "user" ,key="#id")
    public user selectbyprimarykey(integer id)
    {
        return  usermapper.selectbyprimarykey(id);
    }

    @override
    @cacheable(cachenames = "users")
    public list<user> getall()
    {
        return usermapper.getall();
    }

  其中,key如果不设置,会根据我们设置的生成器生成key,如果自己设置的话,有几种方式,下面介绍一下:

a、基本形式

@cacheable(value="cachename", key"#id")

public user method(int id);

b、组合形式

@cacheable(value="cachename", key"t(string).valueof(#name).concat('-').concat(#password))

public user method(int name, string password);

c、对象形式

@cacheable(value="cachename", key"#user.id)

public user method(user user);

d、自定义key生成器

@cacheable(value="gomeo2ocache", keygenerator = "keygenerator")

public user method(user user);

 5、测试

   我们 打开druid的sql监控,然后在swagger中进行操作,在redis desktop manager中查看redis,就可以看到第一次查询执行了数据库查询,并把结果存进了redis中,以后执行同样的查询,在缓存没过期之前,都直接从redis获取,不再执行数据库查询,可见redis缓存成功运行和释放了数据库的压力了;

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 

附:redis windows下简单实用以及redis gui工具redis desktop manager的使用,也简单介绍下:

1、redis windows版的简单使用:

下载redis windows版,解压后看到

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 先点击打开redis-server.exe,再打开redis-cli.exe,redis已经以默认的方式启动起来了,其中redis-server.exe就是redis服务,redis-cli.exe是客户端工具,用来以命令操作redis的;

这时候就可以使用redis,默认密码是空的,端口是6379;我们设置一下密码:

config set requirepass “你的密码”       //设置密码
auth “你的密码”                                   //验证密码是否成功设置

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 flushall ,是清除所有缓存的命令,用来清除重新测试的,

其他命令就不多介绍了,需要用到自行百度

2、redis desktop manager的使用

下载安装包,安装,然后填入密码连接即可

小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存

 

 

三、后续

  第二种方式中注解实现redis缓存的方式有个缺点,就是失效时间都统一配置了,更多时候,我们希望失效时间可以每个方法单独配置,所以二的方法还需要改造,实现失效时间单独配置的功能;还有redis一般我们都会搭建集群实现高可用,关于linux、docker搭建redis集群的方式,这些项目实战干货我们以后再来详细聊;

 

附demogit地址:https://github.com/anson-yang/cloverdemo.git