文章目录
1 添加maven依赖
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2 yml配置文件
spring:
datasource:
username: xx
password: xxxxxx
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT
cache:
type: redis
redis:
database: 0
port: 6379 # Redis服务器连接端口
host: localhost # Redis服务器地址
password: xxxxxx # Redis服务器连接密码(默认为空)
timeout: 5000 # 超时时间
3 配置RedisConfig
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
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.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;
import java.util.Random;
@EnableCaching
@Configuration
public class RedisConfig {
@Bean
public CacheManager RedisCacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
/**
* 新版本中om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)已经被废弃
* 建议替换为om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL)
*/
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化解决乱码的问题
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
// 设置缓存过期时间 为解决缓存雪崩,所以将过期时间加随机值
.entryTtl(Duration.ofSeconds(60 * 60 + new Random().nextInt(60 * 10)))
// 设置key的序列化方式
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
// 设置value的序列化方式
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
// .disableCachingNullValues(); //为防止缓存击穿,所以允许缓存null值
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
// 启用RedisCache以将缓存 put/evict 操作与正在进行的 Spring 管理的事务同步
.transactionAware()
.build();
return cacheManager;
}
}
4 相关注解介绍
4.1 @Cacheable
如果缓存中不存在目标值,则将调用目标方法并将返回的值存入缓存;如果存在,则直接返回缓存中的值,不会执行方法体。即使方法体内进行了数据库的更新操作,也不会执行。
该注解常用参数如下:
- cacheNames/value :存储方法调用结果的缓存的名称
- key :缓存数据使用的key,可以用它来指定,key=”#param”可以指定参数值,也可以是其他属性
- keyGenerator :key的生成器,用来自定义key的生成,与key为二选一,不能兼存
- condition:用于使方法缓存有条件,默认为”” ,表示方法结果始终被缓存。conditon=”#id>1000″表示id>1000的数据才进行缓存
- unless:用于否决方法缓存,此表达式在方法被调用后计算,因此可以引用方法返回值(result),默认为”” ,这意味着缓存永远不会被否决。unless = “#result==null”表示除非该方法返回值为null,否则将方法返回值进行缓存
- sync :是否使用异步模式,默认为false不使用异步
4.2 @CachePut
如果缓存中先前存在目标值,则更新缓存中的值为该方法的返回值;如果不存在,则将方法的返回值存入缓存。
该注解常用参数同@Cacheable,不过@CachePut没有sync 这个参数
4.3 @CacheEvict
如果缓存中存在存在目标值,则将其从缓存中删除
该注解常用参数如下:
- cacheNames/value、key、keyGenerator、condition同@Cacheable
- allEntries:如果指定allEntries为true,Spring Cache将忽略指定的key
清除缓存中的所有元素
,默认情况下为false。 - beforeInvocation:删除缓存操作默认是在对应方法成功执行之后触发的,方法如果因为抛出异常而未能成功返回时也不会触发删除操作。如果指定beforeInvocation为true ,则
无论方法结果如何,无论方法是否抛出异常都会导致删除缓存
。
5 编写service实现层
其它层正常编写即可,与之前并无差别,此处不再展示
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.springboot.entity.User;
import com.company.springboot.mapper.UserMapper;
import com.company.springboot.service.UserService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService {
@Resource
private UserMapper userMapper;
// 当调用这个方法的时候,会从一个名叫user的缓存中查询
@Cacheable(cacheNames = "user", key = "#id")
public User findById(Long id) {
// 如果不存在则查询数据库,并把查询的结果放入缓存中
return userMapper.selectById(id);
}
// 先执行方法体中的代码,成功执行之后删除缓存
@CacheEvict(cacheNames = "user", key = "#id")
public boolean delete(Long id) {
// 删除数据库中具有的数据
return userMapper.deleteById(id) == 1;
}
// 如果缓存中先前存在,则更新缓存;如果不存在,则将方法的返回值存入缓存
@CachePut(cacheNames = "user", key = "#user.id")
public User update(User user) {
userMapper.updateById(user);
return user;
}
@CachePut(cacheNames = "user", key = "#user.id")
public User insert(User user) {
userMapper.insert(user);
return user;
}
}
测试过程不再贴图,如下给出创建该表的sql,有兴趣的可以自行测试
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '用户名',
`sex` tinyint(1) NULL DEFAULT NULL COMMENT '0 男 1 女',
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71479.html