1.项目前期配置
1.1 配置pom.xml
<!-- 引入Spring整合Redis的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.2 配置 application.yml 文件
spring:
# MySQL数据库连接配置
datasource:
url: jdbc:mysql:///springbootdata?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
username: root
password: 123
jpa:
# 显示使用JPA进行数据库查询的SQL语句
show-sql: true
# 配置Redis服务器
redis:
host: 192.168.93.100
port: 6379
# 密码可以为空,但不能不写
password:
1.3 主类加入 @EnableCaching 注解
@EnableCaching // 开启了SpringBoot基于注解的缓存管理实现(Spring技术实现的)
@SpringBootApplication
public class SpringbootCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCacheApplication.class, args);
}
}
2 Spring Boot缓存注解实现
2.1 @EnableCaching注解
@EnableCaching是由Spring框架提供的,Spring Boot框架对该注解进行了继承,该注解需要配置在类 上(在Spring Boot中,通常配置在项目启动类上),用于开启基于注解的缓存支持。
默认查看下表内存库
2.2 @Cacheable注解
一般用于查询;表示将方法的返回值缓存到内存中, key 默认为参数值;cacheNames:命名空间名
@Cacheable注解也是由Spring框架提供的,可以作用于类或方法(通常用在数据查询方法上),用于 对方法的查询结果进行缓存存储。@Cacheable注解的执行顺序是,先进行缓存查询,如果为空则进行 方法查询,并将结果进行缓存;如果缓存中有数据,不进行方法查询,而是直接使用缓存数据。 Cacheable注解提供了多个属性,用于对缓存存储进行相关配置,具体属性及说明如下表所示。
2.3 @CachePut注解
一般用于修改;#result 表示返回值,如果是对象可以打点获取值,用法和@Cacheable注解一致
@CachePut注解是由Spring框架提供的,可以作用于类或方法(通常用在数据更新方法上),该注解的 作用是更新缓存数据。@CachePut注解的执行顺序是,先进行方法调用,然后将方法结果更新到缓存 中。
@CachePut注解也提供了多个属性,这些属性与@Cacheable注解的属性完全相同。
2.4 @CacheEvict注解
一般用于删除;删除 命名空间为 cacheNames 属性值 ,key 属性值 的 内存数据,会立即删除内存中的 key
@CacheEvict注解是由Spring框架提供的,可以作用于类或方法(通常用在数据删除方法上),该注解 的作用是删除缓存数据。@CacheEvict注解的默认执行顺序是,先进行方法调用,然后清除缓存。 @CacheEvict注解提供了多个属性,这些属性与@Cacheable注解的属性基本相同。除此之外, @CacheEvict注解额外提供了两个特殊属性allEntries和beforeInvocation,其说明如下。
1.allEntries属性
allEntries属性表示是否清除指定缓存空间中的所有缓存数据,默认值为false(即默认只删除指定key对 应的缓存数据)。例如@CacheEvict(cacheNames="comment",allEntries= true)表示方法执行后会删除 缓存空间comment中所有的数据。
2.beforeInvocation属性
beforeInvocation属性表示是否在方法执行之前进行缓存清除,默认值为false(即默认在执行方法后再 进行领存清除)例如@CacheEvict(cacheNames="comment",beforeInvocation=true)表示会在方法执 行之前进行缓存清除。
需要注意的是,如果将@CacheEvict注解的beforeInvocation属性设置为true,会存在一定的弊端。例 如在进行数据删除的方法中发生了异常,这会导致实际数据并没有被删除,但是缓存数据却被提前清除 了。
2.5 @Caching注解
上三个的组合注解;用法例 :
@Caching(cacheable = {@Cacheable(cacheNames = "comment", key = "#comment_id")},put = {@CachePut(cacheNames = "comment", key = "#result.author")})
2.6 @CacheConfig注解
用于 Service 层,类上 表示配置上面几个注解的公有属性
@CacheConfig注解作用于类,主要用于统筹管理类中所有使用@Cacheable、@CachePut和 @CacheEvict注解标注的方法中的公共属性,这些公共属性包括cacheNames、keyGenerator、 cacheManager和cacheResolver。
2.7 示例:
package com.example.springboot_cache.service.impl;
import com.example.springboot_cache.domain.Comment;
import com.example.springboot_cache.repository.CommentRepository;
import com.example.springboot_cache.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import java.util.Optional;
//@Service
@CacheConfig(cacheNames = "comment")
public class CommentServiceImpl implements CommentService {
@Autowired
private CommentRepository commentRepository;
@Override
// @Cacheable(cacheNames = "comment") // 表示将方法的返回值缓存到内存中
// @Caching(cacheable = {@Cacheable(key = "#comment_id")})
@Cacheable(unless = "#result == null")
public Comment findByid(int comment_id) {
Optional<Comment> optional = commentRepository.findById(comment_id);
if (optional.isPresent()) {
return optional.get(); // 获取 optional 中的comment对象
}
return null;
}
@Override
@CachePut(key = "#result.id")
// @Caching(put = {@CachePut(key = "#result.author")})
public Comment updateComment(Comment comment) {
commentRepository.updateComment(comment.getAuthor(),comment.getId());
return comment;
}
@Override
@CacheEvict() // 默认key为 形参 comment_id 的值
public void deleteCommentById(int comment_id) {
commentRepository.deleteById(comment_id);
}
}
3 Spring Boot缓存API实现
直接使用:
@Autowired // 简化了Redis操作的模板类,底层分装了Jedis。通过RedisTemplate类完成Redis增删改查操作 private RedisTemplate redisTemplate;
在Spring Boot整合Redis缓存实现中,除了基于注解形式的Redis缓存实现外,还有一种开发中常用的方 式——基于API的Redis缓存实现。下面我们通过Redis API的方式讲解Spring Boot整合Redis缓存的具体 实现。
3.1 示例
package com.example.springboot_cache.service.impl;
import com.example.springboot_cache.domain.Comment;
import com.example.springboot_cache.repository.CommentRepository;
import com.example.springboot_cache.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Service
public class APICommentServiceImpl implements CommentService {
@Autowired
private CommentRepository commentRepository;
@Autowired
// 简化了Redis操作的模板类,底层分装了Jedis。通过RedisTemplate类完成Redis增删改查操作
private RedisTemplate redisTemplate;
@Override
public Comment findByid(int comment_id) {
// 通过RedisTemplate查询缓存中的数据
//
Object obj = redisTemplate.opsForValue().get("comment_" + comment_id);
if(obj != null) {
return (Comment) obj;
}else {
Optional<Comment> optional = commentRepository.findById(comment_id);
if (optional.isPresent()) {
Comment comment = optional.get();
// redisTemplate.opsForValue().set("comment_" + comment_id,comment);
redisTemplate.opsForValue().set("comment_" + comment_id, comment, 1, TimeUnit.DAYS);
return comment;
}
return null;
}
}
@Override
public Comment updateComment(Comment comment) {
commentRepository.updateComment(comment.getAuthor(), comment.getId());
redisTemplate.opsForValue().set("comment_" + comment.getId(),comment);
return comment;
}
@Override
public void deleteCommentById(int comment_id) {
commentRepository.deleteById(comment_id);
redisTemplate.delete("comment_" + comment_id);
}
}
4 自定义Redis缓存序列化机制
4.1 配置类
package com.example.springboot_cache.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
// 设置 Redis 模板类的连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用 JSON 格式序列化对象,将对象的数据缓存成key-value结构
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 解决查询数据转化的异常问题
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(mapper);
// 设置RedisTemlate模板的序列化存储方式
redisTemplate.setDefaultSerializer(jsonRedisSerializer);
return redisTemplate;
}
// 注解开发
// @Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 设置value的序列化方式
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer(); // 设置key的序列化方式
// 创建RedisCacheConfiguration 对象
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1)) // 配置缓存数据默认
// 指定key序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
.disableCachingNullValues(); // null 值不参与序列化
// 创建 RedisCacheManager 并作为返回值
RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build();
return redisCacheManager;
}
}
5. 详细内容
百度网盘链接: https://pan.baidu.com/s/1fQ9tZAXE_ygtuv3mUPNlYw?pwd=m29s
提取码: m29s