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;     } } 
 |