缓存:—存在内存中。
作用: —提高查询性能,减少数据库访问频率。
什么样的数据适合放入缓存: —安全系数低的。—访问频率高 —修改频率低 。
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2.应用程序配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/a165?serverTimeZone=Asia/Shanghai&characterEncoding=UTF8
spring.datasource.username=root
spring.datasource.password=123456
spring.redis.host=192.168.18.165
spring.redis.port=6379
#使用集群缓存接受
#spring.redis.cluster.nodes=192.168.18.165:7001,192.168.18.165:7002,192.168.18.165:7003,192.168.18.165:7004,192.168.18.165:7005,192.168.18.165:7006
#mybatis-plus的CRUD日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3.配置类
@Configuration
public class RedisConfig {
@Bean //把该方法返回的类对象交于spring的IOC容器来管理
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
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);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化 filed value
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(redisSerializer); //
return template;
}
@Bean
public CacheManager cacheManager(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);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
4.开启缓存注解
@SpringBootApplication
@EnableCaching//开启注解缓存驱动
public class ChacheRedisApplication {
public static void main(String[] args) {
SpringApplication.run(ChacheRedisApplication.class, args);
}
}
5.实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private Integer id;
private String name;
}
6.Mapper层
public interface DeptMapper extends BaseMapper<Dept> {
}
7.业务层
@Service
public class DeptService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private RedisTemplate redisTemplate;
public Dept findById(Integer id) {
ValueOperations valueOperations = redisTemplate.opsForValue();
//查询缓存中是否存在该数据
Object o = valueOperations.get("dept:" + id);
System.out.println(o);
if (o!=null && o instanceof Dept){
return (Dept) o;
}
//查询数据库
Dept dept = deptMapper.selectById(id);
if (dept!=null){
//把该数据放入缓存中
valueOperations.set("dept:"+id,dept,20, TimeUnit.HOURS);
}
return dept;
}
}
7.使用缓存注解
@Service
public class DeptChacheService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private RedisTemplate redisTemplate;
//使用与查询的缓存注解
//先从缓存中找名字叫:cacheNames::key 如果存在,则方法不执行,如果不存在会执行方法,并把方法的返回值作为缓存的值
@Cacheable(cacheNames = "dept",key = "#id")
public Dept findById(Integer id) {
Dept dept = deptMapper.selectById(id);
return dept;
}
/**
* 修改缓存与数据库
* @author fey
* @date 2023/7/4 19:15
*/
//先执行方法体,并把方法的返回结果作为缓存的值,修改缓存的值
@CachePut(cacheNames = "dept",key = "#dept.id")
public Dept updateDept(Dept dept){
deptMapper.updateById(dept);
return dept;
}
//删除缓存在执行方法体
@CacheEvict(cacheNames = "dept",key = "#id")
public int delete(Integer id){
deptMapper.deleteById(id);
return 0;
}
}
8.测试
@Autowired
private DeptService deptService;
@Autowired
private DeptChacheService deptChacheService;
@Test
void contextLoads() {
Dept byId = deptService.findById(1);
System.out.println(byId);
}
/**
* 查询缓存
* @date 2023/7/4 19:13
*/
@Test
void test02(){
deptChacheService.findById(1);
}
/**
* 修改缓存
* @date 2023/7/4 19:13
*/
@Test
void test03(){
Dept dept = new Dept(1, "fei");
Dept dept1 = deptChacheService.updateDept(dept);
System.out.println(dept1);
}
/**
* 删除缓存
* @date 2023/7/4 19:17
*/
@Test
void test04(){
deptChacheService.delete(1);
}