肝完了,总结了SpringBoot与缓存的知识点,快速掌握

Posted 我是springmeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了肝完了,总结了SpringBoot与缓存的知识点,快速掌握相关的知识,希望对你有一定的参考价值。

本章给大家带来的是SpringBoot和缓存的学习。同时已经录制了非常详细的视频,如果看文档较为吃力,可以结合视频进行学习,帮你快速掌握SringBoot与缓存。

目录

一、JSR107

 二、Spring缓存抽象

 三、几个重要概念&缓存注解

四、缓存使用

五、整合redis实现缓存

六、整合一个实例


一、JSR107

Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry Expiry

CachingProvider 定义了创建、配置、获取、管理和控制多个 CacheManager 。一个应用可以在运行期访问多个 CachingProvider
CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache ,这些 Cache 存在于 CacheManager 的上下文中。一个 CacheManager 仅被一个 CachingProvider 所拥有。
Cache 是一个类似 Map 的数据结构并临时存储以 Key 为索引的值。一个 Cache 仅被一个 CacheManager 所拥有。
Entry 是一个存储在 Cache 中的 key-value 对。
Expiry 每一个存储在 Cache 中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过 ExpiryPolicy 设置。

 二、Spring缓存抽象

Spring3.1开始定义了org.springframework.cache.Cache

org.springframework.cache.CacheManager接口来统一不同的缓存技术;

并支持使用JCacheJSR-107)注解简化我们的开发;

Cache 接口为缓存的组件规范定义,包含缓存的各种操作集合;
Cache 接口下 Spring 提供了各种 xxxCache 的实现;如 RedisCache EhCacheCache , ConcurrentMapCache 等;
每次调用需要缓存功能的方法时, Spring 会检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
使用 Spring 缓存抽象时我们需要关注以下两点;

1、确定方法需要被缓存以及它们的缓存策略

2、从缓存中读取之前缓存存储的数据

 

 三、几个重要概念&缓存注解

 

SpEL语法的缓存格式

四、缓存使用

1 、引入 spring-boot-starter-cache 模块
2 @ EnableCaching 开启缓存
3 、使用缓存注解
4 、切换为其他缓存
测试缓存对象:

五、整合redis实现缓存

1. 引入 spring-boot-starter-data- redis spring-data- redis

  <groupId>redis.clients</groupId>
<
artifactId>jedis</artifactId>

2.     配置redis连接地址spring.redis.host=192.168.0.108

3.     使用ReditTemplate操作redis

1. redisTemplate.opsForValue ();// 操作字符串
2. redisTemplate.opsForHash ();// 操作 hash
3. redisTemplate.opsForList ();// 操作 list
4. redisTemplate.opsForSet ();// 操作 set
5. redisTemplate.opsForZSet ();// 操作有序 set

redisconfig实现:

@Configuration
public class RedisConfig {
    //过期时间
    private Duration timeToLive = Duration.ofDays(1);

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory){
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(timeToLive)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
                .disableCachingNullValues();

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(configuration).transactionAware().build();
        return redisCacheManager;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(keySerializer());
        template.setHashKeySerializer(keySerializer());
        template.setValueSerializer(valueSerializer());
        template.setHashValueSerializer(valueSerializer());

        return template;
    }


    private RedisSerializer<String> keySerializer(){
        return new StringRedisSerializer();
    }

    private RedisSerializer<Object> valueSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }
}

application.properties的配置:

spring.datasource.username=spring
spring.datasource.password=spring

#开启驼峰命名匹配规则
mybatis.configuration.map-underscore-to-camel-case=true

logging.level.com.dahaiwuliang.cache.mapper=debug

#redis连接
spring.redis.host=192.168.0.108

六、整合一个实例

 * Cacheable的运行流程
 * 1、在方法运行之前,先去缓存按value查找Cache,第一次获取不到就会创建
 * 2、去Cache中查找Entry,使用一个key,默认用方法的参数
 *      key是按某种规则创建的,默认是使用的SimpleKeyGenerator生成
 *      SimpleKeyGenerator的生成策略:
 *          如果没有参数,key=new SimpleKey();
 *          如果有一个参数,key=参数的值
 *          如果有多个参数:key=new SimpleKey(params);
 *
 * 3、如果查到,直接返回;没有查到就调用目标方法
 * 4、将目标方法返回的结果放到缓存里面
 *
 *  cacheNames/value:
 *      指定缓存组件(Cache)的名字,将方法的返回结果放到哪个缓存中,是数组的方式,可以指定多个缓存
 *
 *  key:
 *      Entry里面的key,默认是使用的SimpleKeyGenerator生成;
 *      也可以写SpEL表达式来生成 #a0   #p0  #root.args[0]  #id
 *  keyGenerator:key的生成器,可以自定义一个
 *
 *  cacheManager:指定缓存管理器
 *
 *  condition:指定符合条件的情况下才缓存
 *
 *  unless:否定缓存,和condition正好相反
 *
 *  sync:是否使用异步模式

controller层:

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/getEmployee")
    public Employee getEmployee(Integer id){
        Employee employee = employeeService.getEmp(id);
        return employee;
    }

    @GetMapping("/updateEmployee")
    public Employee update(Employee employee){
        Employee emp = employeeService.updateEmp(employee);
        return emp;
    }

    @GetMapping("/deleteEmployee")
    public String deleteEmp(Integer id){
        employeeService.deleteEmp(id);
        return "success";
    }

    @GetMapping("/emp/{lastName}")
    public Employee getEmployeeByLastName(@PathVariable("lastName") String lastName){
        return employeeService.getEmployeeByLastName(lastName);
    }
}

service层:

 public Employee getEmp(Integer id){
        System.out.println("查询"+id+"员工");
        Employee employee = employeeMapper.getEmpById(id);
        Cache cache = cacheManager.getCache("emp");
        cache.put("emp:"+id,employee);
        return employee;
    }


    /**
     * @CachePut:既调用方法,又更新缓存
     * 修改了数据库的数据,并同时更新缓存
     *  运行机制:
     *      1、先调用目标方法;
     *      2、将目标方法的结果缓存起来
     */
    @CachePut(/*value = "emp",*/key="#result.id")
    public Employee updateEmp(Employee employee){
        System.out.println("update:"+employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

    /**
     * @CacheEvict:清除缓存
     *  allEntries=true清空这个缓存中的所有数据
     *  beforeInvocation=true代表清空缓存操作是在方法执行前就执行了,无论方法是否出现异常,缓存都会被清除
     */
    @CacheEvict(/*value = "emp",*/key = "#id"/*,allEntries = true*/,beforeInvocation = true)
    public void deleteEmp(Integer id){
        System.out.println("deletEmp:"+id);
        //employeeMapper.deleteEmpById(id);
        int a = 10/0;
    }

    /**
     * @Caching 定义复杂的缓存规则
     */
    @Caching(
            cacheable = {
                    @Cacheable(/*value = "emp",*/key = "#lastName")
            },
            put = {
                    @CachePut(/*value = "emp",*/key = "#result.id")
            }

    )
    public Employee getEmployeeByLastName(String lastName){
        System.out.println("getEmployeeByLastName:"+lastName);
        return employeeMapper.getEmpByLastName(lastName);
    }
}

好了,讲解结束,小伙伴们点赞、收藏、评论,一键三连走起呀,下期见~~

以上是关于肝完了,总结了SpringBoot与缓存的知识点,快速掌握的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot学习路线大全之SpringBoot与分布式保姆式教程建议收藏

SpringBoot学习路线大全之SpringBoot与分布式保姆式教程建议收藏

肝完了,我的 MySQL 学习之路

绝了!花3个晚上就肝完了面试100%要问的Spring/MyBatis/Redis…

❤️肝完了,一天掌握数据结构和算法面试题,吊打面试官,建议收藏❤️

❤️肝完了,一天掌握数据结构和算法面试题,吊打面试官,建议收藏❤️