1.1 什么是缓存?
缓存(Cache)是计算机科学中的一种技术,旨在提高数据访问速度。它是一种临时存储机制,用于存储常用或近期访问的数据,以便快速访问,减少延迟
1.2 缓存的原理
1.3 什么样的数据适合放入缓存当中
适合缓存的数据通常是那些需要快速访问、访问频率高、计算成本高且变化不频繁的数据。
1.4 哪个组件可以作为缓存
-
redis组件
-
memory组件
-
ehcache组件 等......
1.5 java使用redis如何实现缓存功能
1.5.1 SpringBoot整合redis配置依赖
使用Maven,可以在pom.xml
中添加以下依赖: 这里使用的是JDK8
java
<dependencies>
<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>
<!--mysql的驱动依赖 3.-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</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>
</dependencies>
1.5.2 修改 application.properties 配置文件 这是示例
java
spring.application.name=springboot-redis-cache
#??????
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=kkkk
#??mybatis???????
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
#????-sql??
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#redis??
spring.redis.host=192.168.202.199
spring.redis.port=6379
spring.redis.database=1
业务层代码
java
@Service
public class ClazzServiceImpl implements ClazzService {
@Autowired
private ClazzDao clazzDao;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public Clazz getById(Integer id) {
//1.查询redis缓存是否命中
ValueOperations<String, Object> forValue = redisTemplate.opsForValue();
Object o = forValue.get("clazz::" + id);
//表示缓存命中
if(o!=null){
return (Clazz) o;
}
//查询数据库
Clazz clazz = clazzDao.selectById(id);
if(clazz!=null){
forValue.set("clazz::" + id,clazz);
}
return clazz;
}
@Override
public Clazz save(Clazz clazz) {
int insert = clazzDao.insert(clazz);
return clazz;
}
@Override
public Clazz update(Clazz clazz) {
//修改数据库
int i = clazzDao.updateById(clazz);
if(i>0){
//修改缓存
redisTemplate.opsForValue().set("clazz::"+clazz.getCid(),clazz);
}
return clazz;
}
@Override
public int delete(Integer cid) {
int i = clazzDao.deleteById(cid);
if(i>0){
//删除缓存
redisTemplate.delete("clazz::"+cid);
}
return i;
}
}
发现: 业务层代码除了要维护核心业务功能外,额外还要维护缓存的代码。
如何解决: 使用AOP面向切面编程。
spring框架。---aop切面来解决。
1.6 使用缓存注解完成缓存
必须spring缓存使用的组件。 序列化
java
@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;
}
开始注解缓存
@EnableCaching
注解在Spring应用中用于启用缓存,当你使用Redis作为缓存提供者时,它的作用是相同的:启用缓存机制并允许你在应用中使用缓存注解,如 @Cacheable
、@CachePut
和 @CacheEvict
。
使用:
java
package com.ykq.service.impl;
import com.ykq.dao.ClazzDao;
import com.ykq.entity.Clazz;
import com.ykq.service.ClazzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
/**
* @Author:
* @Description:
* @Date: Create in 14:36 2024/7/24
*/
@Service
public class ClazzServiceImpl implements ClazzService {
@Autowired
private ClazzDao clazzDao;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
//Cacheable:表示查询时使用的注解。 cacheNames:缓存的名称 key:缓存的唯一表示值
// 1. 查询缓存中是否存在名称为cacheNames::key的值
//2.如果存在则方法不会执行
// 3. 如果不存在则执行方法体并把方法的返回结果放入缓存中cacheNames::key
@Cacheable(cacheNames ={ "clazz"}, key = "#id")
@Override
public Clazz getById(Integer id) {
//查询数据库
Clazz clazz = clazzDao.selectById(id);
return clazz;
}
@Override
public Clazz save(Clazz clazz) {
int insert = clazzDao.insert(clazz);
return clazz;
}
//CachePut:表示修改时使用的注解.
// 1. 先执行方法体
// 2. 把方法的返回结果放入缓存中
@CachePut(cacheNames = "clazz", key = "#clazz.cid")
public Clazz update(Clazz clazz) {
//修改数据库
int i = clazzDao.updateById(clazz);
return clazz;
}
//CacheEvict:表示删除时使用的注解
// 1. 先执行方法体
// 2. 把缓存中名称为cacheNames::key的值删除
@CacheEvict(cacheNames = "clazz", key = "#cid")
@Override
public int delete(Integer cid) {
int i = clazzDao.deleteById(cid);
return i;
}
}