1 添加maven依赖
<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 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.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;
import java.util.Random;
@EnableCaching
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@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);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60 * 60 + new Random().nextInt(60 * 10)))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.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;
@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;
|