当前位置: 首页 > news >正文

springboot之redis缓存探索

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

好了,其它的就不介绍了

@Cacheable

        此注解表明在进入方法之前,Spring 会先去缓存服务器中査找对应 key 的缓存值,如果找到缓存值,那么 Spring 将不会再调用方法,而是将缓存值读出,返回给调用者;如果没有找到缓存值,那么 Spring 就会执行你的方法,将最后的结果通过 key 保存到缓存服务器中

第一次执行时redis是没有缓存的  Cacheable去redis里面查找对应的key是找不到的,便会往下执行方法

而我去数据库删除一条数据后,再去执行这个注解标识的方法

 

 可以看到,如果有往下执行方法我的数据必定是两条数据,然后数据与我数据库数据不对应,说明取了redis里面的缓存,并没有执行方法,控制台也没有调用日志

 @CachePut

  主要针对方法配置,能够根据方法的返回值对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用,在其他地方写的是根据方法的请求参数对其结果进行缓存,实际是按方法返回值进行缓存的

这里一般都用做更新缓存

 这里第一次执行缓存

 可以看到它缓存的内容为实际该方法的返回对象

如果我还以之前的id去提交数据

 

 可以看到该注解每次都会真实调用标识的方法

@CachEvict

主要针对方法配置,能够根据一定的条件对缓存进行清空

 以上为我实验之前缓存的数据

我调用CachEvict标识的方法后该缓存redis里面就找不到了

 @CacheConfig

所有的@CacheXXXX()里面都有一个value=“xxx”的属性时可以一次性声明,如果你在你的方法写别的名字,那么依然以方法的名字为准。

@CacheConfig(cacheNames="redisCache")

 

 

 可以看到我使用了CacheConfig后,我保存了一个key=2的一条学信息,统一使用CacheConfig标识的value

@Caching

在缓存的应用场景中 通常我们缓存某一个数据更新了,可能也会影响到其它位置的缓存,需要一个联动更新

    @GetMapping("/testCaching/{id}")
    @ApiOperation(value = "联动更新缓存",notes = "统一value标识")
    @Caching(cacheable = @Cacheable(cacheNames = "testCaching",key = "#id"),evict = @CacheEvict(cacheNames = "redisCache",key = "#id"))
    public Student testCaching(@PathVariable("id") String id){
        return studentService.getById(id);
    }

 我这一步想要缓存 testCaching::key 然后失效 redisCache::key

 

 我调用这个联动更新缓存的方法后

 

 可以看到redisCache这个缓存消失了,出现了testCaching,说明实验成功了

这是个分组注解,它能够同时应用于其他缓存的注解

参数解释
value缓存的名称,在 spring 配置文件中定义,必须指定至少一个。就是个自己取的名字,通过它指明了第一次调用这个方法时返回将被存在内存的哪里。
key缓存的 key,可选。如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
condition缓存的限定条件,满足就缓存,不满足就不缓存
allEntries是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
beforeInvocation是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存

 好了上代码吧

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zkb</groupId>
    <artifactId>springboot-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-redis</name>
    <description>springboot-redis</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
        <swagger-ui.version>1.5.22</swagger-ui.version>
        <springfox.version>2.9.2</springfox.version>
        <swagger-bootstrap-ui.version>1.9.1</swagger-bootstrap-ui.version>
        <fastjson.version>1.2.47</fastjson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger-ui.version}</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger-ui.version}</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox.version}</version>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>${swagger-bootstrap-ui.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.zkb.SpringbootRedisApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
server:
    port: 8081
spring:
    application:
        name: springboot-redis
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        name: defaultDataSource
        url: jdbc:mysql://${MYSQL_HOST:zkbplus-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:test_demo1}?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
        username: root
        password: zkb.com
        type: com.zaxxer.hikari.HikariDataSource
    jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
    redis:
        host: zkbplus-redis
        port: 6379
        password: zkb123456
        database: 3
logging:
    level:
        com:
            fs: debug
mybatis-plus:
    configuration:
        map-underscore-to-camel-case: true
        auto-mapping-behavior: full
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    mapper-locations: classpath:mapping/*.xml
    global-config:
        # 逻辑删除配置
        db-config:
            # 删除前
            logic-not-delete-value: 0
            # 删除后
            logic-delete-value: 1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zkb.mapper.StudentMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zkb.entity.Student">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="age" property="age" />
    </resultMap>


</mapper>
package com.zkb.conf;

import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;


@Configuration
public class RedisConfig {


    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        RedisCacheConfiguration config = RedisCacheConfiguration
                .defaultCacheConfig();

        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));

        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }

}
package com.zkb.conf;

import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Arrays;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi1() {
        return new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo()).select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .apis(RequestHandlerSelectors.basePackage("com.zkb.controller"))
                .paths(PathSelectors.any()).build().securitySchemes(apiKeyList()).groupName("系统接口");
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("系统接口文档")
                .description("这是系统接口文档说明")
                .contact(new Contact("h2", "", ""))
                .version("1.0")
                .build();
    }

    private List<ApiKey> apiKeyList() {
        return Arrays.asList(new ApiKey("登录token", "token", In.HEADER.name()),
                new ApiKey("设备类型(android,ios,pc)---必填", "deviceType", In.HEADER.name()));
    }
}



package com.zkb.constant;

public class CacheTimes {

    public static final String D1 = "cache_1d";
}
package com.zkb.controller;

import com.zkb.constant.CacheTimes;
import com.zkb.entity.Student;
import com.zkb.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequestMapping("/test")
@RestController
@Api(value = "Student", tags = "Student")
@CacheConfig(cacheNames="redisCache")
public class TestController {

    @Autowired
    StudentService studentService;

    @GetMapping("list")
    @ApiOperation(value = "获取列表")
    @Cacheable(value = CacheTimes.D1)
    public List<Student> getList(){
        return studentService.list();
    }

    @PostMapping("save")
    @ApiOperation(value = "保存")
    @CachePut("students")
    public String save(Student student){
         studentService.save(student);
        return "success";
    }

    @GetMapping("/getStudentById/{id}")
    @ApiOperation(value = "根据id获取学生信息")
    @Cacheable(value = CacheTimes.D1,key = "#id")
    public Student getStudentById(@PathVariable("id") String id){
        return studentService.getById(id);
    }

    @GetMapping("/deleteById/{id}")
    @ApiOperation(value = "根据id删除学生信息")
    @CacheEvict(value = CacheTimes.D1,key = "#id")
    public void deleteById(@PathVariable("id") String id){
         studentService.removeById(id);
    }

    @GetMapping("/getStuById/{id}")
    @ApiOperation(value = "根据id获取学生信息", notes = "统一value标识")
    @Cacheable(key = "#id")
    public Student getStuById(@PathVariable("id") String id){
        return studentService.getById(id);
    }

    @GetMapping("/delStuById/{id}")
    @ApiOperation(value = "根据id删除学生信息",notes = "统一value标识")
    @CacheEvict(key = "#id")
    public void delStuById(@PathVariable("id") String id){
         studentService.removeById(id);
    }

    @GetMapping("/testCaching/{id}")
    @ApiOperation(value = "联动更新缓存",notes = "统一value标识")
    @Caching(cacheable = @Cacheable(cacheNames = "testCaching",key = "#id"),evict = @CacheEvict(cacheNames = "redisCache",key = "#id"))
    public Student testCaching(@PathVariable("id") String id){
        return studentService.getById(id);
    }


}
package com.zkb.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("student")
public class Student extends Model<Student> {
    private Integer id;
    private String name;
    private Integer age;
}
package com.zkb.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zkb.entity.Student;

public interface StudentMapper extends BaseMapper<Student> {
}
package com.zkb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zkb.entity.Student;
import com.zkb.mapper.StudentMapper;
import com.zkb.service.StudentService;
import org.springframework.stereotype.Service;

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

}
package com.zkb.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.zkb.entity.Student;

public interface StudentService extends IService<Student> {
}
package com.zkb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication
@EnableCaching // 允许使用注解进行缓存
@MapperScan(basePackages = "com.zkb.mapper")
@EnableSwagger2
public class SpringbootRedisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootRedisApplication.class, args);
    }

}

例子:https://download.csdn.net/download/qq_14926283/86608542

相关文章:

  • 高并发系统架构设计之微服务篇: 秒杀系统下的服务拆分
  • jieba
  • 学术英语写作(更新中)
  • 关于穿越机FPV视频果冻效应的讨论
  • 顺序表(c++类模板实现)
  • Leetcode 698. 划分为k个相等的子集
  • 开发工具安装
  • 图解字符串匹配算法:从Brute-Force到KMP,一下子就整明白了
  • Python语言:散修笔记
  • 为什么要学习Linux内核,如何学习?
  • 块级作用域绑定
  • 8.7 迁移学习域适应
  • 高企认定评分标准有哪些?
  • halcon提取数据集中指定图片并进行裁剪
  • 使用PdfSharp从模板生成Pdf文件
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 08.Android之View事件问题
  • Angular4 模板式表单用法以及验证
  • docker容器内的网络抓包
  • JavaScript创建对象的四种方式
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java教程_软件开发基础
  • Java精华积累:初学者都应该搞懂的问题
  • nodejs:开发并发布一个nodejs包
  • React Native移动开发实战-3-实现页面间的数据传递
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 前端_面试
  • 强力优化Rancher k8s中国区的使用体验
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 主流的CSS水平和垂直居中技术大全
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • C# - 为值类型重定义相等性
  • Prometheus VS InfluxDB
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #QT(TCP网络编程-服务端)
  • #Z2294. 打印树的直径
  • ${factoryList }后面有空格不影响
  • (1)SpringCloud 整合Python
  • (2020)Java后端开发----(面试题和笔试题)
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (四)Linux Shell编程——输入输出重定向
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)Linux下编译安装log4cxx
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .jks文件(JAVA KeyStore)
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET 回调、接口回调、 委托
  • .Net语言中的StringBuilder:入门到精通
  • :中兴通讯为何成功
  • @RequestMapping-占位符映射
  • [ C++ ] STL---string类的使用指南