小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存
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();
运行后可以查看到缓存中已经写入,读取也正常读取出来
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缓存成功运行和释放了数据库的压力了;
附:Redis Windows下简单实用以及Redis GUI工具Redis desktop manager的使用,也简单介绍下:
1、Redis Windows版的简单使用:
下载Redis Windows版,解压后看到
先点击打开Redis-server.exe,再打开Redis-cli.exe,Redis已经以默认的方式启动起来了,其中Redis-server.exe就是Redis服务,Redis-cli.exe是客户端工具,用来以命令操作Redis的;
这时候就可以使用Redis,默认密码是空的,端口是6379;我们设置一下密码:
config set requirepass “你的密码” //设置密码
auth “你的密码” //验证密码是否成功设置
flushall ,是清除所有缓存的命令,用来清除重新测试的,
其他命令就不多介绍了,需要用到自行百度
2、Redis desktop manager的使用
下载安装包,安装,然后填入密码连接即可
三、后续
第二种方式中注解实现Redis缓存的方式有个缺点,就是失效时间都统一配置了,更多时候,我们希望失效时间可以每个方法单独配置,所以二的方法还需要改造,实现失效时间单独配置的功能;还有Redis一般我们都会搭建集群实现高可用,关于Linux、docker搭建Redis集群的方式,这些项目实战干货我们以后再来详细聊;
附demoGIT地址:https://github.com/anson-yang/cloverDemo.git
小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存的更多相关文章
- 小白的springboot之路(一)、环境搭建、第一个实例
小白的springboot之路(一).环境搭建.第一个实例 0- 前言 Spring boot + spring cloud + vue 的微服务架构技术栈,那简直是爽得不要不要的,怎么爽法,自行度娘 ...
- 小白的springboot之路(十八)、i18n多语言支持(后端篇)
0-前言 在有些系统中,比如网站,往往需要支持多国语言,英文版中文版什么的,这个其实也不难: 今天我们就来介绍spring boot中用i18n在后端支持多语言: 当然,也可以直接在前端用i18n直接 ...
- 小白的springboot之路(二)、集成swagger
0-前言 现在的项目开发,基本都是前后端分离,后端专注于API接口开发,都需要编写和维护API接口文档.如果你还在用Word来编写接口文档,那你就out了,这个时候,当当当当~神兵利器swagger隆 ...
- 小白的springboot之路(十六)、mybatis-plus 的使用
0-前言 mybatis plus是对mybatis的增强,集成mybatis plus后,简单的CRUD和分页就不用写了,非常方便,五星推荐: 1-集成 1-1.添加依赖 <!-- .集成my ...
- 小白的springboot之路(七)、事务支持
0-前言 事务管理对于企业级应用来说必不可少,用来确保数据的完整性和一致性: 1-开启事务 spring boot支持编程式事务和声明式事务,用声明式事务即可: spring boot开启事务非常简单 ...
- 小白的springboot之路(六)、跨域解决方案CORS
0-前言 前后端分离.分布式集群,经常都会涉及到跨域访问,而浏览器基于同源策略,正常情况下是不能跨域的,这就需要我们解决跨域访问问题:spring boot解决跨域也比较简单: 1-CORS跨域解决方 ...
- 小白的springboot之路(五)、集成druid
0-前言 Druid阿里巴巴开源的一个java数据库连接池,是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能:集成它能够方便我们对数据库连接进行监控和分析,下面我们来集成它: ...
- 小白的springboot之路(三)、集成mybatis与MySQL
0.前言 mybatis属于半自动的ORM,相比hibernate这种全自动的ORM,兼顾了性能与易用:目前企业项目中,基本都是mybatis的天下:今天就来整合mybatis与MySQL: 1.整合 ...
- 小白的springboot之路(四)、mybatis-generator自动生成mapper和model、dao
0-.前言 在用mybatis开发项目中,数据库动辄上百张数据表,如果你一个一个去手动编写,比较耗费时间:还好,我们有mybatis-generator插件,只需简单几步就能自动生成mybatis的m ...
随机推荐
- 7.30 NOIP模拟10
T1.辣鸡 考试的时候竟然被我以“麻烦”弃掉了,赛后发现这题好水啊,直接sort一下寻找四周即可. T2.模板 考试时期望得分70,实际得分5 首先看到这种题基本就是线段树,我们以时间为下标,对每一个 ...
- JS 接口定义及实现的例子
//定义一个函数,目的是将参数中的第二个函数所有属性放到第一个参数中,目的是将接口中所有方法放到实现类中 Object.extend=function(destination,source){ for ...
- DAY 3 数论专场
2019-07-23 今天的题目一个比一个神仙,很早之前就在讨论今天是不是晚上回宾馆就没脑子了,后来发现,是中午.... 一上午就讲了一个PPT,然而标题就两个子---数论... 这谁顶的住....整 ...
- 每天一道算法题-leetcode136-只出现一次的数字
前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...
- [LC]747题 Largest Number At Least Twice of Others (至少是其他数字两倍的最大数)
①中文题目 在一个给定的数组nums中,总是存在一个最大元素 . 查找数组中的最大元素是否至少是数组中每个其他数字的两倍. 如果是,则返回最大元素的索引,否则返回-1. 示例 1: 输入: nums ...
- 使用ssh管理远程主机
首先,找两台虚拟机ping通,因为这个实验目的是通过客户端访问服务端. 咱们进入虚拟机后,打开终端,输入命令:rpm -qa | grep openssh 卸载 输入命令: yum remove ...
- nyoj 101-两点距离 (数学)
101-两点距离 内存限制:64MB 时间限制:3000ms 特判: No 通过数:27 提交数:74 难度:1 题目描述: 输入两点坐标(X1,Y1),(X2,Y2)(0<=x1,x2,y1, ...
- 【SpringBoot | Redis】SpringBoot整合Redis
SpringBoot整合Redis 1. pom.xml中引入Redis相关包 请注意,这里我们排除了lettuce驱动,采用了jedis驱动 <!-- redis的依赖 --> < ...
- TCP/IP网络基础知识
TCP/IP是一组用于实现网络互联的通信协议,通常称为TCP/IP协议族.包括TCP.IP.UDP.ICMP.RIP.TELNETFTP.SMTP.ARP.TFTP等. 一.TCP/IP模型将协议分为 ...
- 拎壶学python3-----(5)python之格式化输出
一.格式化输入可以减少代码开发量如下是格式化输出: 上边的%是什么意思呢?%是一个占位符,s代表字符串的类型. 二.我们看下边的例子 看使用%d %i的用法. %d %i 这种格式化只能用数字来填补占 ...