SSM之spring注解式缓存redis

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS SQL Server,独享型 2核4GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: SSM之spring注解式缓存redis

一.spring注解redis

1.导入依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>ssm2</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>ssm2 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
    <!--添加jar包依赖-->
    <!--1.spring 5.0.2.RELEASE相关-->
    <spring.version>5.0.2.RELEASE</spring.version>
    <!--2.mybatis相关-->
    <mybatis.version>3.4.5</mybatis.version>
    <!--mysql-->
    <mysql.version>5.1.44</mysql.version>
    <!--pagehelper分页jar依赖-->
    <pagehelper.version>5.1.2</pagehelper.version>
    <!--mybatis与spring集成jar依赖-->
    <mybatis.spring.version>1.3.1</mybatis.spring.version>
    <!--3.dbcp2连接池相关 druid-->
    <commons.dbcp2.version>2.1.1</commons.dbcp2.version>
    <commons.pool2.version>2.4.3</commons.pool2.version>
    <!--4.log日志相关-->
    <log4j2.version>2.9.1</log4j2.version>
    <!--5.其他-->
    <junit.version>4.12</junit.version>
    <servlet.version>4.0.0</servlet.version>
    <lombok.version>1.18.2</lombok.version>
    <ehcache.version>2.10.0</ehcache.version>
    <slf4j-api.version>1.7.7</slf4j-api.version>
    <redis.version>2.9.0</redis.version>
    <redis.spring.version>1.7.1.RELEASE</redis.spring.version>
  </properties>
  <dependencies>
    <!--1.spring相关-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--2.mybatis相关-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <!--mysql-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <!--pagehelper分页插件jar包依赖-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>${pagehelper.version}</version>
    </dependency>
    <!--mybatis与spring集成jar包依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <!--3.dbcp2连接池相关-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>${commons.dbcp2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>${commons.pool2.version}</version>
    </dependency>
    <!--4.log日志相关依赖-->
    <!--核心log4j2jar包-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--web工程需要包含log4j-web,非web工程不需要-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--5.其他-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servlet.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- jsp依赖-->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>
    <!--    做服务端参数校验 JSR303 的jar包依赖 -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.7.Final</version>
    </dependency>
    <!--    用来SpringMVC支持json数据转换-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.3</version>
    </dependency>
    <!--    shiro相关依赖 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>${ehcache.version}</version>
    </dependency>
    <!-- slf4j核心包 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j-api.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>${slf4j-api.version}</version>
      <scope>runtime</scope>
    </dependency>
    <!--用于与slf4j保持桥接 -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>${redis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>${redis.spring.version}</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>ssm2</finalName>
    <resources>
      <!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>*.properties</include>
          <include>*.xml</include>
        </includes>
      </resource>
    </resources>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven.compiler.plugin.version}</version>
          <configuration>
            <source>${maven.compiler.source}</source>
            <target>${maven.compiler.target}</target>
            <encoding>${project.build.sourceEncoding}</encoding>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.mybatis.generator</groupId>
          <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.2</version>
          <dependencies>
            <!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
            <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>${mysql.version}</version>
            </dependency>
          </dependencies>
          <configuration>
            <overwrite>true</overwrite>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

2.具体操作

配置工厂(spring-redis.xml)

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          destroy-method="destroy">
        <property name="poolConfig" ref="poolConfig"/>
        <!--IP地址 -->
        <property name="hostName" value="${redis.hostName}"/>
        <!--端口号  -->
        <property name="port" value="${redis.port}"/>
        <!--如果Redis设置有密码  -->
        <property name="password" value="${redis.password}"/>
        <!--客户端超时时间单位是毫秒  -->
        <property name="timeout" value="${redis.timeout}"/>
    </bean>

 redis操作模板,使用该对象可以操作redis

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <!--开启事务  -->
        <property name="enableTransactionSupport" value="true"/>
    </bean>

配置缓存管理器

<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
    <constructor-arg name="redisOperations" ref="redisTemplate"/>
    <!--redis缓存数据过期时间单位秒-->
    <property name="defaultExpiration" value="${redis.expiration}"/>
    <!--是否使用缓存前缀,与cachePrefix相关-->
    <property name="usePrefix" value="true"/>
    <!--配置缓存前缀名称-->
    <property name="cachePrefix">
        <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">
            <constructor-arg index="0" value="-cache-"/>
        </bean>
    </property>
</bean>
<bean id="cacheKeyGenerator" class="com.zking.ssm.redis.CacheKeyGenerator"></bean>
    <!--7.启用缓存注解功能-->
    <cache:annotation-driven cache-manager="redisCacheManager" key-generator="cacheKeyGenerator"/>
</beans>

二.redsi三个注解的使用

@Cacheable(可以读取数据,也可以写数据)

@Cacheable注解用于标记一个方法的结果可以被缓存。 当调用该方法时,Spring首先检查缓存是否已经存在结果。 如果存在,将直接从缓存中返回结果,而不执行方法。 如果结果不在缓存中,则执行方法并将结果缓存起来,以便后续调用时使用。

java复制代码

@Cacheable(value = "books", key = "#isbn")public Book getByIsbn(String isbn) { // 从数据库中获取书籍信息的逻辑 }

@CachePut(只读数据)

@CachePut注解用于更新缓存中的内容。 当使用注解标记的方法被调用时,Spring会更新缓存中的值,而不管缓存中是否已经存在相应的键值对。@CachePut

java复制代码

@CachePut(value = "books", key = "#book.isbn")public Book updateBook(Book book) { // 更新数据库中书籍信息的逻辑return book; }

@CacheEvict注解用于从缓存中删除数据。 可以通过指定属性来确定要清除的缓存,通过属性来指定要删除的项。valuekey

java复制代码

@CacheEvict(value = "books", key = "#isbn")publicvoiddeleteByIsbn(String isbn) { // 从数据库中删除书籍信息的逻辑 }

这些注解在执行耗时操作(如数据库查询或API调用)的应用程序中非常有用。 通过缓存这些操作的结果,可以加快后续调用的速度,减少应用程序的响应时间。

三.redis击穿穿透雪崩

1.定义

Redis击穿

Redis击穿是指一个缓存key非常热门,在某一个时间点过期的时候,恰好又有大量的并发请求过来访问这个key,导致所有请求都打到了数据库上,从而导致数据库压力过大,甚至宕机。 为了避免这种情况,可以使用互斥锁(mutex)或者分布式锁来解决。

Redis穿透

Redis穿透是指一个请求查询一个不存在的缓存key,这个请求就会直接打到数据库上,如果请求量很大,数据库就会承受巨大的压力。 为了避免这种情况,可以使用布隆过滤器来处理缓存穿透的问题,或者在缓存层做参数校验和异常处理。

Redis雪崩

Redis雪崩是指在某一个时间段,缓存集中过期失效,导致所有请求都落到数据库上,造成数据库压力急剧增大,甚至宕机的现象。 为了避免这种情况,可以采用多级缓存架构,设置不同的超时时间,避免缓存同时失效。 同时,也可以设置热点数据永久不过期,避免热点数据集中过期。 另外,还可以使用限流和降级等手段来应对高并发情况。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
27天前
|
监控 Java 调度
Spring中的任务调度:探索@Scheduled和@Schedules注解的威力
Spring中的任务调度:探索@Scheduled和@Schedules注解的威力
26 0
|
27天前
|
消息中间件 NoSQL Java
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
45 1
|
2天前
|
存储 缓存 NoSQL
【Redis】3、Redis 作为缓存(Redis中的穿透、雪崩、击穿、工具类)
【Redis】3、Redis 作为缓存(Redis中的穿透、雪崩、击穿、工具类)
33 0
|
5天前
|
缓存 NoSQL Redis
如何在Python中使用Redis或Memcached进行缓存?
如何在Python中使用Redis或Memcached进行缓存?
9 2
|
9天前
|
存储 Java 程序员
【JavaEE进阶】 Spring使用注解存储对象
【JavaEE进阶】 Spring使用注解存储对象
|
10天前
|
NoSQL Java Redis
Spring boot 实现监听 Redis key 失效事件
【2月更文挑战第2天】 Spring boot 实现监听 Redis key 失效事件
30 0
|
11天前
|
Java Spring
Spring 使用注解注入失败,调用内容时提示空指针
Spring 使用注解注入失败,调用内容时提示空指针
10 0
|
14天前
|
开发框架 Java 测试技术
Spring Boot 项目中使用 `@Autowired` 注解,合理吗?
Spring Boot 项目中使用 `@Autowired` 注解,合理吗?
101 1
Spring Boot 项目中使用 `@Autowired` 注解,合理吗?
|
27天前
|
存储 缓存 NoSQL
Redis--缓存设计与性能优化
Redis--缓存设计与性能优化
|
27天前
|
存储 NoSQL 关系型数据库
轻松打卡:使用Spring Boot和Redis Bitmap构建高效签到系统【redis实战 四】
轻松打卡:使用Spring Boot和Redis Bitmap构建高效签到系统【redis实战 四】
36 0

热门文章

最新文章