参考
- https://blog.csdn.net/weixin_43749805/article/details/131399516
- https://juejin.cn/post/7076244567569203208
- https://blog.csdn.net/oJingZhiYuan12/article/details/126386904
注意
-
class java.lang.Integer cannot be cast to class com.xiaqiuchu.demo.entity.Student (java.lang.Integer is in module java.base of loader 'bootstrap'; com.xiaqiuchu.demo.entity.Student is in unnamed module of loader 'app')
注解缓存时缓存的方法缓存值,update 返回的是数字类型,导致缓存查询的时候报错转换失败。 -
entity 类需要 implements java.io.Serializable ,否则可能会导致缓存储存时序列化失败或错误。
环境
环境 | 版本 | 操作 |
---|---|---|
windows | 10 | |
vs code | 1.84.2 | |
Spring Boot Extension Pack | v0.2.1 | vscode插件 |
Extension Pack for Java | v0.25.15 | vscode插件 |
JDK | 11 | |
Springboot | 2.3.12.RELEASE | |
mybatis-spring-boot-starter | 2.1.4 | mvn依赖 |
spring-boot-starter-cache | mvn依赖 | |
Apache Maven | 3.8.6 | |
Redis | 3.0.504 | windows 版本,已停更,建议 linux 中使用 |
步骤
配置
- 添加
pom.xml
依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 在配置文件中
application.properties
增加配置。
不仅仅这些配置,还有其他配置以及连接池的配置
# redis配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
# 连接池配置,连接池配置还需要添加其他依赖。 https://juejin.cn/post/7076244567569203208
- 在
src\main\java\com\xiaqiuchu\demo\config
增加RedisConfig.java
。
package com.xiaqiuchu.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// key 序列化类
template.setKeySerializer(new StringRedisSerializer());
// value 序列化类
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
使用
- 代码操作。
package com.xiaqiuchu.demo.service;
import java.time.Duration;
import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.mapper.StudentMapper;
@Service
public class StudentService {
@Resource
StudentMapper studentMaper;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 手动管理缓存
* @param id
* @return
*/
public Student findByIdFromCache(Integer id){
String cacheKey = "StudentService" + id;
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
if(redisTemplate.hasKey(cacheKey) == null || redisTemplate.getExpire(cacheKey) < 1){
System.out.println("==查询数据库==");
valueOperations.set(cacheKey, studentMaper.findById(id), Duration.ofHours(2));
}
return (Student) valueOperations.get(cacheKey);
}
}
- 注解方式
注意:注解方式是缓存的方法返回值,但是像 mybatis 中 update 操作默认返回的是更新条数,如果直接返回更新条数就会导致缓存储存为数字类型,在查询的时候报错
class java.lang.Integer cannot be cast to class com.xiaqiuchu.demo.entity.Student (java.lang.Integer is in module java.base of loader 'bootstrap'; com.xiaqiuchu.demo.entity.Student is in unnamed module of loader 'app')
注解方式获取 key 可以通过
.
方式获取对象的属性。
package com.xiaqiuchu.demo.service;
import javax.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.mapper.StudentMapper;
@Service
public class StudentService {
@Resource
StudentMapper studentMaper;
// 该注解用于标记方法的返回结果可以被缓存。当下次调用相同的方法时,如果缓存中存在相同的参数,则直接从缓存中获取结果,而不执行方法体内的代码。如果缓存中不存在相同的参数,则执行方法体内的代码,并将结果存入缓存中。
@Cacheable(value = "StudentService", key = "#id")
public Student findById(Integer id){
System.out.println("==查询==");
return studentMaper.findById(id);
}
public Integer insert(Student student){
return studentMaper.insert(student);
}
// 该注解用于标记方法的返回结果需要放入缓存。无论缓存中是否已存在相同的参数,每次调用该方法都会执行方法体内的代码,并将结果存入缓存中。
// 方法返回类型要一致,不然储存的就是 Integer。。。
@CachePut(value = "StudentService", key = "#student.id")
public Student updateById(Student student){
Integer updateNum = studentMaper.updateById(student);
Assert.isTrue(updateNum > 0, "更新失败");
return student;
}
// 该注解用于标记方法执行后需要清除特定的缓存项。可以指定要清除的缓存项的key,或者通过allEntries参数设置为true来清除所有缓存项。
@CacheEvict(value = "StudentService", key = "#id")
public Integer deleteById(Integer id){
System.out.println("==删除==");
return studentMaper.deleteById(id);
}
}
- Springboot2 Springboot Redisspringboot2 springboot lettuce redis springboot2 springboot redis springboot2 springboot步骤redis 集群springboot2 springboot redis springboot2 springboot2 springboot springboot2 springboot swagger3 swagger springboot2 springboot mybatis springboot2 springboot spring3 spring springboot2 springboot后台 管理系统