文章主要内容
一、SpringCache 介绍
二、SpringCache 注解
三、注解方式实现Redis缓存(Windows版Redis)
四、RedisUtils工具类原生方式实现Redis缓存(Windows版Redis)
一、SpringCache介绍
在Spring Boot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口。
如果程序中没有定义类型为CacheManager的Bean组件或者是名为cacheResolver的CacheResolver缓存解析器,Spring Boot将尝试选择并启用以下缓存组件(按照指定的顺序):
(1)Generic
(2)JCache (JSR-107)(EhCache 3、Hazelcast、Infinispan等)
(3)EhCache 2.x
(4)Hazelcast
(5)Infinispan
(6)Couchbase
(7)Redis
(8)Caffeine
(9)Simple
上面按照Spring Boot缓存组件的加载顺序,列举了支持的9种缓存组件,在项目中添加某个缓存管理组件(例如Redis)后,Spring Boot项目会选择并启用对应的缓存管理器。如果项目中同时添加了多个缓存组件,且没有指定缓存管理器或者缓存解析器(CacheManager或者cacheResolver),那么Spring Boot会按照上述顺序在添加的多个缓存中优先启用指定的缓存组件进行缓存管理。
Spring Boot默认缓存管理中,没有添加任何缓存管理组件能实现缓存管理。这是因为开启缓存管理后,Spring Boot会按照上述列表顺序查找有效的缓存组件进行缓存管理,如果没有任何缓存组件,会默认使用最后一个Simple缓存组件进行管理。Simple缓存组件是Spring Boot默认的缓存管理组件,它默认使用内存中的ConcurrentMap进行缓存存储,所以在没有添加任何第三方缓存组件的情况下,可以实现内存中的缓存管理,但是我们不推荐使用这种缓存管理方式
当在Spring Boot默认缓存管理的基础上引入Redis缓存组件,即在pom.xml文件中添加Spring Data Redis依赖启动器后,SpringBoot会使用RedisCacheConfigratioin当做生效的自动配置类进行缓存相关的自动装配,容器中使用的缓存管理器是RedisCacheManager, 这个缓存管理器创建的Cache为 RedisCache, 进而操控redis进行数据的缓存
org.springframework.boot
spring-boot-starter-data-redis
核心思想:当我们调用一个方法时会把该方法的参数和返回结果最为一个键值对存放在缓存中,等下次利用同样的参数来调用该方法时将不会再执行,而是直接从缓存中获取结果进行返回。
理解:springboot 的缓存机制是通过切面编程 aop来实现的
二、SpringCache 注解
Spring Cache 提供了 @Cacheable 、@CachePut 、@CacheEvict 、@Caching 等注解,在方法上使用。
基于注解方式SpringCache引入Redis做缓存,需要先了解@EnableCaching、@CacheConfig、@Cacheable、@CachePut、@CacheEvict、@Caching相关注解的使用
1、@EnableCaching
开启缓存功能,一般放在启动类上或者自定义的RedisConfig配置类上。
2、@CacheConfig
当我们需要缓存的地方越来越多,可以使用@CacheConfig(cacheNames = "cacheName")注解在 class 之上来统一指定value的值,统一管理keys,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。
示例:@Service
@CacheConfig(cacheNames = "categories")
public class CategoryServiceImpl implements CategoryService{
......
}
3、@Cacheable
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。 查看源码,属性值如下:属性/方法名解释value缓存名,指定了缓存存放在哪块命名空间(必须)
cacheNames与value差不多,二选一即可
key缓存的key,可以使用SPEL标签自定义缓存的key
keyGeneratorkey的生存器。key/keyGenerator二选一使用
cacheManager指定缓存管理器
cacheResolver指定获取解析器
condition条件符合则缓存
unless条件符合则不缓存
sync是否使用异步模式,默认为false
4、@CachePut
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。 查看源码,属性值同上@Cacheable差不多
5、@CacheEvict
使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上。
查看源码,属性值与@Cacheable差不多,独有的两个属性如下:属性/方法名解释allEntries是否清空所有缓存,默认为false。如果指定为true,则方法调用后将立即清空所有的缓存
beforeInvocation是否在方法执行前就清空所有缓存,默认为false。如果指定为true,则方法执行前就会清空所有的缓存
6、@Caching
该注解可以实现同一个方法上同时使用多种注解。可从其源码看出:public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
三、注解方式实现Redis缓存(Windows版Redis)
1、数据库及数据环境准备CREATE DATABASE `redistest`CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `redistest`;
CREATE TABLE `user`(
id INT(11)NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255)DEFAULT NULL,
`password` VARCHAR(255)DEFAULT NULL,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES(1,'张三',"123456789");
INSERT INTO `user` VALUES(2,'李四',"asdfghj");
INSERT INTO `user` VALUES(3,'王麻子',"kjfdskjf");
INSERT INTO `user` VALUES(4,'小明',"hellorworld");
INSERT INTO `user` VALUES(5,'李华',"redis");
2、构建一个SpringBoot项目,勾选相应的模块,添加Pom依赖
添加其他的Pom依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
3、application.properties配置文件# ============数据库============
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/redistest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=admin
# ============mybatis============
mybatis.mapper-locations=classpath:/mapper/*.xml
mybatis.type-aliases-package=com.cqy.pojo
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# ============redis============
# 默认是使用0号数据库,这里我们使用1号,笔者现在0号有其他数据- -
spring.redis.database=1
spring.redis.host=localhost
spring.redis.port=6379
# 默认密码为空
spring.redis.password=
# 连接池最大连接数
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间
spring.redis.lettuce.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
4、pojo实体类@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private int id;
private String name;
private String password;
}
5、dao层的Mapper接口@Repository
@Mapper
public interface UserMapper {
/**
* 增加
* @param user
* @return
*/
public int addUser(User user);
/**
* 删除
* @param id
* @return
*/
public int deleteUser(@Param("id") int id);
/**
* 修改
* @param user
* @return
*/
public int updateUser(User user);
/**
* 查询获取所有User对象
* @return
*/