分布式缓存
Java与Mysql数据库的连接,是最影响效率的时候,频繁的查询数据库会导致系统的响应变慢。而与数据库的交互中,大部分工作是用于查询,将Mysql的数据查询结果返回后台,相当于将硬盘中的数据读入内存中,影响了查询效率。将要查询的数据放入缓存中,再次查询时将不再走数据库,而直接走内存中获取。
直接与程序一起放在一个内存中,也会影响程序的运行时资源,也是由于不同的服务直接无法共享缓存,所以使用分布式缓存。而Redis作为优秀的内存型NoSql与Mybatis的二级缓存结合可以有效解决问题。
0、开启打印SQL语句
logging.level.com.wdd.dao=debug
1、实体类(数据库)
Java放入Redis需要实现序列化。
@Data
public class Emp implements Serializable {
private String id;
private String name;
private String path;
private Double salary;
private String age;
}
2、mapper.xml
<mapper namespace="com.wdd.dao.EmpDao">
<!--查询所有 -->
<select id="findAll" resultType="Emp">
select id,name,path,salary,age from t_emp
</select>
<!-- 插入数据 -->
<insert id="save" parameterType="Emp" useGeneratedKeys="true" keyProperty="id">
insert into t_emp value (#{id},#{name},#{path},#{salary},#{age})
</insert>
</mapper>
3、测试查询
- 每发一次findAll()请求,就会在控制台打印一次sql执行语句
4、引入Redis实现Cache接口(org.apache.ibatis.cache.Cache
包)
public class RedisCache implements Cache {
//存入缓存需要一个id,实际上是mapper.xml中的namespace
private String id;
//写出有参构造,为了Mybatis实现
public RedisCache(String id) {
this.id = id;
}
//私有方法用于本类中调用
private RedisTemplate<Object,Object> getRedisTemplate(){
RedisTemplate<Object,Object> redisTemplate = (RedisTemplate) AppUtils.getBean("redisTemplate");
//key的序列化策略为String类型序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
//Hashkey的序列化策略为String类型序列化
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
@Override
public String getId() {
return this.id;
}
@Override//放入缓存,存入Hash结构中,id为namespace,Hashkey为sql语句,hashvalue为查询结果
public void putObject(Object key, Object value) {
getRedisTemplate().opsForHash().put(id, key.toString(), value);
}
@Override//取出缓存,若两次查询sql语句一致,直接从缓存中给出数值
public Object getObject(Object key) {
return getRedisTemplate().opsForHash().get(id,key.toString());
}
@Override//删除指定缓存信息,未实现
public Object removeObject(Object key) {
return null;
}
//清除缓存,在进行增,删,改时会清空namespace的缓存,直接删除hash结构,也会删除关联此namespace的缓存
@Override
public void clear() {
getRedisTemplate().opsForHash().delete(id);
}
@Override
public int getSize() {
return getRedisTemplate().opsForHash().size(id).intValue();
}
}
5、获取Bean工具类
@Component
public class AppUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static Object getBean(String name){
return applicationContext.getBean(name);
}
}
6、使用缓存
<mapper namespace="com.wdd.dao.EmpDao">
<cache type="com.wdd.cache.RedisCache"/>
......
</mapper>
7、测试
- findAll()请求第一次会走Mysql,并把结果存入Redis,第二次击中缓存,直接返回查询数据;
- save()请求走数据库,改变数据库数据,Redis中数据清空;
- 再次请求findAll()又会请求数据库,重新存入Redis