<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.5.3</version>
</dependency>
选择缓存类型
spring:
cache:
type: redis
SpringBoot启动类开启缓存注解
@EnableCaching
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空,主要用作删除
有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。
@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User save(User user) {
}
所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。
@CacheConfig是一个类级别的注解
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.3version>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
<version>2.5.3version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.3.4version>
dependency>
<dependency>
<groupId>com.h2databasegroupId>
<artifactId>h2artifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
data-h2.sql
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
INSERT INTO user2 (id, name, age) VALUES
(1, 'Jone', 18),
(2, 'Jack', 20),
(3, 'Tom', 28),
(4, 'Sandy', 21),
(5, 'Billie', 24);
schema-h2.sql
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
CREATE TABLE user2
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (id)
);
spring:
cache:
type: redis
#H2配置
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:test
username: root
password: test
#H2初始化
sql:
init:
#表结构
schema-locations: classpath:db/schema-h2.sql
#表数据
data-locations: classpath:db/data-h2.sql
redis:
host: Redis地址
password: Redis密码
database: 0
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
@SpringBootApplication
@MapperScan("com.peppa.springcache.mapper")
@ComponentScan("com.peppa")
@EnableCaching
public class SpringCacheTestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCacheTestApplication.class, args);
}
}
其中配置了RedisCacheManager
@Configuration
public class CacheConfig {
@Bean
@Primary
public RedisCacheManager cacheManager1Hour(RedisConnectionFactory connectionFactory){
RedisCacheConfiguration config=instanceConfig(3600L);
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.transactionAware()
.build();
}
@Bean
public RedisCacheManager cacheManager1Min(RedisConnectionFactory connectionFactory){
RedisCacheConfiguration config=instanceConfig(60L);
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.transactionAware()
.build();
}
private RedisCacheConfiguration instanceConfig(Long ttl){
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
//去掉各种@JsonSerialize的注解的解析
objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false);
//只针对非空值进行序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//将类型序列化到属性json字符串中
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(ttl))
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
}
/*
自定义缓存Key规则
*/
@Bean
public KeyGenerator springCacheCustomeKeyGenerator(){
return new KeyGenerator(){
@override
public Object generate(Object o,Method method,Object... objects){
retrun o.getClass().getSimpleName()+"_"
+method.getName()+"_"
+ StringUtils.arrayToDelimitedString(objects,"_");
}
}
}
User
@Data
@Builder
//一定要序列化,Redis存储必须序列化实体类
public class User implements Serializable {
private Long id;
private String name;
private Integer age;
private String email;
}
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
@Service
public class UserService {
@Autowired
UserMapper userMapper;
@Cacheable(value = {"user"},key = "#root.methodName",cacheManager = "cacheManager1Min")
public List<User> select(){
List<User> users = userMapper.selectList(null);
return users;
}
@CachePut(value = {"user"},key = "#root.args[0]")
public User insert(Long id){
User user = User.builder().id(id).build();
int insert = userMapper.insert(user);
return user;
}
@Cacheable(value = {"user"},keyGenerator="springCacheCustomeKeyGenerator")
public User selectOne(Long id){
User user = userMapper.selectById(id);
return user;
}
@CacheEvict(value = {"user"},key = "#root.args[0]")
public int delete(Long id){
int insert = userMapper.deleteById(id);
return insert;
}
}