一、关于多表关系直接的缓存处理
- 此时我们只测试了
缓存对一个表的CRUD操作
, 也完全可以实现分布式缓存的处理
; 如果此时我们再创建一个emp
表, 对emp表进行CRUD
操作也是可行的; 但是User表和Emp表, 当清空User表的缓存对Emp表缓存没有任何影响; - 有人会说, 都是不同的表肯定没关系了, 其实说的也对, 假如说
项目中表查询之间没有任何关联查询, 使用上一篇文章就完全可以解决, 也不会出现任何问题
; - 但是如果
这两个表之间存在关联关系
了呢? 此时问题就出现了, 比如我们再mybatis中所说的那样, 出现额外SQL
的情况, 就涉及到多表的操作
, 此时就会出现问题;
问题:
- 比如
User
中包含了Emp属性
, 当以后我们更改了Emp信息
, 就会清空Emp中的缓存信息
; 但是User的缓存还没有清空, 当下次再查询User的信息, 仍然查询到的是Emp更像前的信息;
使用<cache-ref namespace="com.zy.dao.UserDao"/>
, 将多个有关联关系的表的缓存放到了一起;
二、缓存优化策略
- 对放入redis中key进行优化; key的长度不要太长;
MD5散列算法
/**
* Description: 自定义Redis缓存实现
*
* @author
* @date Created on 2020/7/27 16:55
*/
public class RedisCache implements Cache {
private final String id;
// 必须存在构造方法
public RedisCache(String id) {
// id 就是当前放入缓存的mapper的namespace ---> com.zy.dao.UserDao
System.out.println("id =============> " + id);
this.id = id;
}
// 返回cache的唯一标识
@Override
public String getId() {
return this.id;
}
// 往缓存中放值 --> 使用 RedisTemplate往缓存中放值
// key ---> -983043073:3242099914:com.zy.dao.UserDao.findAll:0:2147483647:SELECT id, name, age, bir FROM t_user:SqlSessionFactoryBean
@Override
public void putObject(Object key, Object value) {
// 使用hash类型作为缓存存储模型 <key, <hashkey, value>> ==> <namespace <当前方法的key, 返回值>>
getRedisTemplate().opsForHash().put(id, getKeyToMD5(key.toString()), value);
}
// 往缓存中取值, 这个key
// key ---> -983043073:3242099914:com.zy.dao.UserDao.findAll:0:2147483647:SELECT id, name, age, bir FROM t_user:SqlSessionFactoryBean
@Override
public Object getObject(Object key) {
System.out.println("key = " + key);
// 根据key从redis的hash类型中key获取数据
return getRedisTemplate().opsForHash().get(id, getKeyToMD5(key.toString()));
}
// 为mybatis的保留方法, 默认没有实现
@Override
public Object removeObject(Object o) {
System.out.println("根据指定key删除缓存");
return null;
}
// 当执行增删改会调用这个方法
@Override
public void clear() {
System.out.println("清空缓存");
getRedisTemplate().delete(id); // 清空缓存
}
// 用来计算缓存数量
@Override
public int getSize() {
// 获取hash中key value的数量
return getRedisTemplate().opsForHash().size(id).intValue();
}
//封装redisTemplate
private RedisTemplate getRedisTemplate(){
//通过application工具类获取redisTemplate
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
// 封装一个对key进行md5的处理方法
private String getKeyToMD5(String key) {
return DigestUtils.md5DigestAsHex(key.getBytes());
}
}