1.缓存技术
缓存实际上是为了减轻数据库服务器的负载。使用缓存,可以将一些常用的数据放入到缓存中,在使用这些数据的时候,首先从缓存中查找,如果缓存中没有,才会到数据库中查询。
|
2.Spring Boot 缓存技术实现
Ehcache:将数据放入JVM内存中。支持2级:内存和硬盘
Redis: 存储在内存中的非关系型数据库。缓存数据库
|
3.前期准备springboot+mybatis+thymeleaf实现的商品CRUD实现
在springboot+mybatis+thymeleaf实现的商品CRUD基础上添加缓存功能
4.Spring Boot 整合Ehcache 缓存
4.1 打开pom.xml文件,引入ehcache相关的启动器以及jar坐标
org.springframework.boot spring-boot-starter-cache
net.sf.ehcache ehcache
|
4.2创建Ehcache的配置文件,提供ehcache的基本配置
文件名:ehcache.xml
位置:src/main/resources/ehcache.xml
ehcach配置:找到ehcache的jar包,打开ehcache-failsafe.xml文件,内容复制到ehcache.xml文件中。
maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <persistence strategy="localTempSwap"/> defaultCache> maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <persistence strategy="localTempSwap"/> cache>
|
4.3打开application.properties,设置ehcache.xml的路径
#配置ehcache配置文件的路径 spring.cache.ehcache.config=classpath:/ehcache.xml
|
4.4 修改启动类,开启缓存策略
@SpringBootApplication /*SpringBoot启动时,告诉springBoot去哪里扫描mybatis的mapper接口,生成实现类的对象*/ @MapperScan("com.xz.mapper") @EnableCaching /*开启Cache缓存*/ public class SpringBootMybatisThymeleafApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMybatisThymeleafApplication.class, args); } }
|
4.5 修改service业务层,指定哪些业务方法需要进行缓存
@Service @Transactional public class GoodsServiceImpl implements GoodsService { @Autowired GoodsMapper goodsMapper;
@Override
/*@Cacheable采用users的缓存策略,对当前查询的结果做缓存处理*/ @Cacheable(value="users") public List getGoodsAll() { return goodsMapper.selectAll(); } }
|
4.6 序列化实体类
@AllArgsConstructor @NoArgsConstructor @Data @ToString public class Goods implements Serializable { private String id; private String name; private double price; private String image; }
|
4.7 启动启动类,查看结果
第一次查询走mysql数据库,后面查询走ehcache缓存。
|
4.8 @Cacheable 与@CacheEvict 注解讲解
4.8.1 @Cacheable注解
@Cacheable 作用:把方法的返回值添加到 Ehcache 中做缓存
Value 属性:指定一个 Ehcache 配置文件中的缓存策略,如果没有给定value,则表示使用默认的缓存策略。
Key 属性:给存储的值起个名称。在查询时如果有名称相同的,那么则知己从缓存中将数据返回。
如果没有给定key,则表示使用方法的参数作为存储值的名称。
代码演示:查询单个商品信息
@RequestMapping("/getOne") @ResponseBody public Goods getOne(String id){ Goods goods=goodsService.getGoodsOne(id,1); return goods; }
@Override @Cacheable(value="users",key = "#num") public Goods getGoodsOne(String id,int num) { return goodsMapper.selectById(id); }
|
|
4.8.2 @CacheEvict注解
@CacheEvict 作用:清除缓存。
应用:当对缓存数据进行增,删,改操作时,需要数据同步。
代码演示:删除商品信息
@Override
/*@CacheEvict(value="users",allEntries=true) 清除缓存中以 users 缓存策略缓存的对象 */ @CacheEvict(value = "users",allEntries = true) public void delGoods(String id) { goodsMapper.deleteById(id); }
|
|
5. Spring Boot 整合redis 缓存(单机版)
5.1 打开linux 虚拟机,启动redis的服务器
5.2 打开pom.xml,添加redis相关的坐标
org.springframework.boot spring-boot-starter-data-redis
|
5.3 打开application.properties全局配置文件,进行redis的相关配置
#redis相关配置 #连接redis服务器的主机名ip spring.redis.host=192.168.180.130 #连接redis服务器端口号 spring.redis.port=6379 #连接redis服务器的密码 spring.redis.password=123456 #配置连接redis使用的数据库索引 spring.redis.database=0 #配置redis连接池 #配置最大连接数.设置负数是无限值 spring.redis.jedis.pool.max-active=10 #最大空闲连接数 spring.redis.jedis.pool.max-idle=3 #配置最小空闲连接数 spring.redis.jedis.pool.min-idle=0 #设置最大等待时间ms spring.redis.jedis.pool.max-wait=-1
|
5.4 创建 RedisTemplate对象: 用于执行 Redis 操作的方法
编写RedisConfig的配置类,在配置类中提供获取RedisTemplate对象的bean方法
/** * 获取RedisTemplate对象的配置类 */ @Configuration public class RedisConfig { @Bean public RedisTemplate getRedisTemplate(RedisConnectionFactory factory){ RedisTemplate redisTemplate=new RedisTemplate(); //设置连接的工厂对象 redisTemplate.setConnectionFactory(factory); //设置序列化器 :实现序列化和反序列化 //设置key的序列化器 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置value的序列化器 redisTemplate.setValueSerializer(new StringRedisSerializer()); return redisTemplate; } }
|
序列化器:实现序列化和反序列化操作
StringRedisSerializer : 简单的字符串序列化
JdkSerializationRedisSerializer: 序列化Java对象(默认)
Jackson2JsonRedisSerializer: 序列化Object对象为json格式字符串
5.5 拷贝JsonUtils的工具类到utils文件夹下
JsonUtils:实现对象和json格式的序列化的操作
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* Title: pojoToJson
* Description:
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param clazz 对象中的object类型
* @return
*/
public static T jsonToPojo(String jsonData, Class beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* Title: jsonToList
* Description:
* @param jsonData
* @param beanType
* @return
*/
public static List jsonToList(String jsonData, Class beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
|
5.5 修改service层,添加redis的缓存
@Service @Transactional public class GoodsServiceImpl implements GoodsService { @Autowired GoodsMapper goodsMapper; @Autowired RedisTemplate redisTemplate;
@Override public List getGoodsAll() { List list=null; //判断redis数据库中是否存在,如果存在,直接获取,如果不存在,从mysql中获取,并存入到redis中 if(redisTemplate.hasKey("goodsList")){ list= JsonUtils.jsonToList(redisTemplate.opsForHash().values("goodsList").toString(),Goods.class); }else{ list=goodsMapper.selectAll(); Map map=new HashMap<>(); for (Goods goods:list) { map.put(goods.getId(),JsonUtils.objectToJson(goods)); } redisTemplate.opsForHash().putAll("goodsList",map); } return list; } }
|