1. 什么是缓存
缓存(Cache)是一种高效的数据存储机制,用于临时存储经常访问的数据,以提高数据访问速度和系统性能。
2. 缓存的原理
缓存的原理是基于局部性原理和数据冗余,通过在存储层之间增加一个快速访问的中间层,将经常访问的数据存储在这个中间层中,以减少访问原始数据源的时间和频率。
3. 什么样的数据适合放入缓存
1. 查询频率高且修改频率低
2. 数据安全性低
4. java使用redis如何实现缓存功能
@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切面来解决。
5. 使用缓存注解完成缓存功能
必须spring缓存使用的组件。
@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;
}
开启缓存注解
使用
@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;
}
}