• 6.SpringBoot与缓存


    目录

    6.1 SpringBoot内置缓存

    步骤①:导⼊依赖

    步骤②:启⽤缓存

     步骤③:修改Service的实现类

    6.2 SpringBoot整合Redis

    ①导⼊springboot整合redis的starter

    ②进⾏基础配置

     ③使⽤springboot整合redis的专⽤客户端接⼝操作

    各种类型的数据操作接⼝如下:

     redis客户端选择

    切换客户端为jedis 

    redis中使⽤缓存 

    6.3SpringBoot整合Ehcache 

    Ehcache

    特性

    EhCache 与 Redis 相⽐

    整合步骤 

    1:导⼊Ehcache的坐标

     2:配置缓存技术实现使⽤Ehcache

    3.创建controller

    4.创建service

     5.修改引导类

     6.4 SpringBoot整合Memcaced

     1.导⼊xmemcached的坐标

     2.配置memcached

    3.配置实体类

     4.创建配置类获取memcached客户端对象

    5.使⽤xmemcached客户端操作缓存,注⼊MemcachedClient对象

     6.controller

    7.引导类


    6.1 SpringBoot内置缓存

    springboot技术提供有内置的缓存解决⽅案,可以帮助开发者快速开启缓存技术,并使⽤缓存技术进⾏数据的快速操作。

    步骤①:导⼊依赖

    
        org.springframework.boot
        spring-boot-starter-cache
    

    步骤②:启⽤缓存

    在引导类上⽅标注注解@EnableCaching配置springboot程序中可以使⽤缓存

    1. @SpringBootApplication
    2. @MapperScan("com.qfedu.dao")
    3. @EnableCaching//开启内置缓存功能
    4. public class Demo5SpringbootExampleApplication {
    5. public static void main(String[] args) {
    6. SpringApplication.run(Demo5SpringbootExampleApplication.class, args);
    7. }
    8. }

     步骤③:修改Service的实现类

    在Service的实现类CustomerServiceImpl添加@Cacheable注解缓存

    1. @Override
    2. @Cacheable(value = "cacheHome",key = "#identity")
    3. public Customer findCustomerById(String identity) {
    4. return customerMapper.findCustomerById(identity);
    5. }

            在业务⽅法上⾯使⽤注解@Cacheable声明当前⽅法的返回值放⼊缓存中,其中要指定缓存的存储位置,以及缓存中保存当前⽅法返回值对应的名称。上例中value属性描述缓存的存储位置,可以理解为是⼀个存储空间名,key属性描述了缓存中保存数据的名称。

            使⽤@Cacheable注解后,执⾏当前操作,如果发现对应名称在缓存中没有数据,就正常读取数据,然后放⼊缓存;如果对应名称在缓存中有数据,就终⽌当前业务⽅法执⾏,直接返回缓存中的数据。

    6.2 SpringBoot整合Redis

    ①导⼊springboot整合redis的starter

    
        org.springframework.boot
        spring-boot-starter-data-redis
    

    ②进⾏基础配置

    spring:
      redis:
        #端口(不配置默认为6379)
        port: 6379
        #地址(不配置默认为localhost)
        host: localhost
        #密码
        password: 123456

     ③使⽤springboot整合redis的专⽤客户端接⼝操作

    此处使⽤的是RedisTemplate

    1. @SpringBootTest
    2. class Demo7SpringbootRedisApplicationTests {
    3. @Autowired
    4. private RedisTemplate redisTemplate;
    5. @Test
    6. void setValue(){
    7. ValueOperations operations = redisTemplate.opsForValue();
    8. operations.set("username","zhangsanfeng");
    9. }
    10. @Test
    11. void getValue(){
    12. ValueOperations operations = redisTemplate.opsForValue();
    13. Object username = operations.get("username");
    14. System.out.println(username);
    15. }
    16. @Test
    17. void setHashValue() {
    18. HashOperations hashOperations = redisTemplate.opsForHash();
    19. hashOperations.put("msg","key","aaa");
    20. }
    21. @Test
    22. void getHashValue() {
    23. HashOperations hashOperations = redisTemplate.opsForHash();
    24. Object o = hashOperations.get("msg", "key");
    25. System.out.println(o);
    26. }
    27. }

    在操作redis时,需要先确认操作何种数据,根据数据种类得到操作接⼝。例如使⽤opsForValue()获取string类型的数据操作接⼝,使⽤opsForHash()获取hash类型的数据操作接⼝,剩下的就是调⽤对应api操作了。

    各种类型的数据操作接⼝如下:

    redis内部不提供java对象的存储格式,因此当操作的数据以对象的形式存在时,会进⾏序列化转码。为了⽅便开发者使⽤基于字符串为数据的操作,springboot整合redis时提供了专⽤的API接⼝StringRedisTemplate,你可以理解为这是RedisTemplate的⼀种指定数据泛型的操作API。

    1. @SpringBootTest
    2. class RedisTests {
    3. @Autowired
    4. private StringRedisTemplate stringRedisTemplate;
    5. @Test
    6. void setValue(){
    7. ValueOperations operations = stringRedisTemplate.opsForValue();
    8. operations.set("username","zhangsanfeng");
    9. }
    10. @Test
    11. void getValue(){
    12. ValueOperations operations = stringRedisTemplate.opsForValue();
    13. Object username = operations.get("username");
    14. System.out.println(username);
    15. }
    16. @Test
    17. void setHashValue() {
    18. HashOperations hashOperations = stringRedisTemplate.opsForHash();
    19. hashOperations.put("msg","key","loading");
    20. }
    21. @Test
    22. void getHashValue() {
    23. HashOperations hashOperations = stringRedisTemplate.opsForHash();
    24. Object o = hashOperations.get("msg", "key");
    25. System.out.println(o);
    26. }
    27. }

     redis客户端选择

    我们习惯⽤的客户端技术是jedis , 但是springBoot默认使⽤的是lettucs作为默认的客户端技术.

    lettcus与jedis对⽐:

    • jedis连接Redis服务器是直连模式,当多线程模式下使⽤jedis会存在线程安全问题,解决⽅案可以通过配置连接池使每个连接专⽤。
    • lettcus基于Netty框架进⾏与Redis服务器连接,底层设计采⽤StatefulRedisConnection。 StatefulRedisConnection⾃身是线程安全的,可以保障并发访问安全问题,所以⼀个连接可以被多线程复⽤。

    切换客户端为jedis 

    1.导⼊jedis坐标

    
        org.springframework.boot
        spring-boot-starter-data-redis
    
    
        redis.clients
        jedis
    

    2.配置客户端技术类型,设置为jedis即可直接使用

    spring:
      redis:
        #端口(不配置默认为6379)
        port: 6379
        #地址(不配置默认为localhost)
        host: localhost
        #密码
        password: 123456
        #切换客户端
        client-type: jedis
        jedis:
          pool:
            max-active: 10

    redis中使⽤缓存 

    需求:⽣成4位数随机验证码,存再redis缓存中,再从缓存中获取数据,时效性为10秒。

    步骤:

    1.    导⼊redis坐标(之前操作过了)
    2.    配置缓存技术实现使⽤redis

    redis作为缓存使⽤相关的配置,⾪属于spring.cache.redis节点下,注意不要写错位置了。

    spring:
      redis:
        #端口(不配置默认为6379)
        port: 6379
        #地址(不配置默认为localhost)
        host: localhost
        #密码
        password: 123456
        #切换客户端
        client-type: jedis
      cache:
        #修改缓存供应商
        type: redis
        redis:
          #key是否使用前缀
          use-key-prefix: false
          #key的前缀
          key-prefix:
          #是否允许key的value值为null
          cache-null-values: true
          #缓存时效时间
          time-to-live: 10s

    3.编写controller

    1. @RestController
    2. @RequestMapping("/cache")
    3. public class RedisController {
    4. @Autowired
    5. private RedisService redisService;
    6. /**
    7. * 生成code
    8. * @return
    9. */
    10. @GetMapping
    11. public String createCode(){
    12. String code = redisService.createCode("");
    13. System.out.println(code);
    14. return code;
    15. }
    16. @PostMapping
    17. public String getCode(){
    18. //从redis缓存中获取的,与service的返回值无关
    19. String code = redisService.getCode("");
    20. return code;
    21. }
    22. }

     4.编写service

    1. @Service
    2. public class RedisService {
    3. @CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
    4. public String createCode(String code) {
    5. int max=10000;
    6. int min=1000;
    7. Random random=new Random();
    8. String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
    9. return strCode;
    10. }
    11. @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    12. public String getCode(String code){
    13. return null;
    14. }
    15. }

    5.在引导类打开缓存

    1. @SpringBootApplication
    2. @EnableCaching//打开缓存开关
    3. public class Demo7SpringbootRedisApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(Demo7SpringbootRedisApplication.class, args);
    6. }
    7. }

    总结

    1.    springboot使⽤redis作为缓存实现需要导⼊redis的坐标
    2.    修改设置,配置缓存供应商为redis,并提供对应的缓存配置

    6.3SpringBoot整合Ehcache 

    Ehcache

    EhCache 是⼀个纯 Java 的进程缓存框架,具有快速、精⼲等特点,是 Hibernate 中默认CacheProvider。Ehcache 是⼀种⼴泛使⽤的开源 Java 分布式缓存。主要⾯向通⽤缓存,Java EE 和轻量级容器。

    特性

    • 快速、简单
    • 多种缓存策略
    • 缓存数据有两级:内存和磁盘,因此⽆需担⼼容量问题
    • 缓存数据会在虚拟机重启的过程中写⼊磁盘
    • 可以通过RMI、可插⼊API等⽅式进⾏分布式缓存
    • 具有缓存和缓存管理器的侦听接⼝
    • ⽀持多缓存管理器实例,以及⼀个实例的多个缓存区域
    • 提供Hibernate的缓存实现

    EhCache 与 Redis 相⽐

    • EhCache 直接在jvm虚拟机中缓存,速度快,效率⾼;但是缓存共享麻烦,集群分布式应⽤不⽅便。
    • Redis 是通过 Socket 访问到缓存服务,效率⽐ EhCache 低,⽐数据库要快很多,处理集群和分布式缓存⽅便,有成熟的⽅案。如果是单个应⽤或者对缓存访问要求很⾼的应⽤,⽤ EhCache 。如果是⼤型系统,存在缓存共享、分布式部署、缓存内容很⼤的,建议⽤ Redis。
    • EhCache 也有缓存共享⽅案,不过是通过 RMI 或者 Jgroup 多播⽅式进⾏⼴播缓存通知更新,缓存共享复杂,维护不⽅便;简单的共享可以,但是涉及到缓存恢复,⼤数据缓存,则不合适。

    整合步骤 

    1:导⼊Ehcache的坐标

    
        org.springframework.boot
        spring-boot-starter-cache
    
    
    
        net.sf.ehcache
        ehcache
    

     2:配置缓存技术实现使⽤Ehcache

    yml

    spring:
      cache:
        type: ehcache
        ehcache:
          config: classpath:ehcache.xml

    resourcrs/ehcachexml

    1. "1.0" encoding="UTF-8"?>
    2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
    4. <diskStore path="D:\ehcache" />
    5. <defaultCache
    6. eternal="false"
    7. diskPersistent="false"
    8. maxElementsInMemory="1000"
    9. overflowToDisk="false"
    10. timeToIdleSeconds="60"
    11. timeToLiveSeconds="60"
    12. memoryStoreEvictionPolicy="LRU" />
    13. <cache
    14. name="codeMsg"
    15. eternal="false"
    16. diskPersistent="false"
    17. maxElementsInMemory="1000"
    18. overflowToDisk="false"
    19. timeToIdleSeconds="10"
    20. timeToLiveSeconds="10"
    21. memoryStoreEvictionPolicy="LRU" />
    22. ehcache>

    注意前⾯的案例中,设置了数据保存的位置是codeMsg,这里我们也创建一个名为codeMsg的缓存空间,不然找不到会报错

    3.创建controller

    1. @RestController
    2. @RequestMapping("/cache")
    3. public class EhcacheController {
    4. @Autowired
    5. private EhcacheService ehcacheService;
    6. /**
    7. * 生成code
    8. * @return
    9. */
    10. @GetMapping
    11. public String createCode(){
    12. String code = ehcacheService.createCode("");
    13. System.out.println(code);
    14. return code;
    15. }
    16. @PostMapping
    17. public String getCode(){
    18. String code = ehcacheService.getCode("");
    19. return code;
    20. }
    21. }

    4.创建service

    1. @Service
    2. public class EhcacheService {
    3. @CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
    4. public String createCode(String code) {
    5. int max=10000;
    6. int min=1000;
    7. Random random=new Random();
    8. String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
    9. return strCode;
    10. }
    11. @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    12. public String getCode(String code){
    13. return null;
    14. }
    15. }

     5.修改引导类

    1. @SpringBootApplication
    2. @EnableCaching//
    3. public class DemoSpringbootEhcacheApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(DemoSpringbootEhcacheApplication.class, args);
    6. }
    7. }

    总结

    1.    springboot使⽤Ehcache作为缓存实现需要导⼊Ehcache的坐标
    2.    修改设置,配置缓存供应商为ehcache,并提供对应的缓存配置⽂件

     6.4 SpringBoot整合Memcaced

            memcache是⼀套分布式的⾼速缓存系统,⽬前被许多⽹站使⽤以提升⽹站的访问速度,尤其对于⼀些⼤型的、需要频繁访问数据库的⽹站访问速度提升效果⼗分显著。
            springboot并没有⽀持使⽤memcached作为其缓存解决⽅案,也就是说在type属性中没有memcached的配置选项,这⾥就需要更变⼀下处理⽅式了。

            memcached⽬前提供有三种客户端技术,分别是 Memcached Client for Java 、 SpyMemcached 和 Xmemcached ,其中性能指标各⽅⾯最好的客户端是Xmemcached,本次整合就使⽤这个作为客户端实现技术了。下⾯开始使⽤Xmemcached

     1.导⼊xmemcached的坐标

    
    
        com.googlecode.xmemcached
        xmemcached
        2.4.7
    
    
    
        org.projectlombok
        lombok
    
    
    
        org.springframework.boot
        spring-boot-configuration-processor
        true
    

     2.配置memcached

    application.yml

    memcached:
      servers: localhost:11211  #memcached默认对外服务端⼝11211
      poolSize: 10
      opTimeout: 5000

    3.配置实体类

    1. @Component
    2. @ConfigurationProperties(prefix = "memcached")
    3. @Data
    4. public class XmemcachedProperties {
    5. private String servers;
    6. private int poolSize;
    7. private long opTimeout;
    8. }

     4.创建配置类获取memcached客户端对象

    1. /**
    2. * 该类返回⼀个客户端对象
    3. */
    4. @Configuration
    5. public class XmemcacheConfig {
    6. @Autowired
    7. private XmemcachedProperties xmemcachedProperties;
    8. @Bean
    9. public MemcachedClient getMemcachedClient(){
    10. MemcachedClientBuilder builder = new XMemcachedClientBuilder(xmemcachedProperties.getServers());
    11. builder.setConnectionPoolSize(xmemcachedProperties.getPoolSize());
    12. builder.setOpTimeout(xmemcachedProperties.getOpTimeout());
    13. MemcachedClient client = null;
    14. try {
    15. client = builder.build();
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. }
    19. return client;
    20. }
    21. }

    5.使⽤xmemcached客户端操作缓存,注⼊MemcachedClient对象

    1. @Service
    2. public class XmemcacheService {
    3. @Autowired
    4. private MemcachedClient memcachedClient;
    5. public String createCode(String code) {
    6. int max=10000;
    7. int min=1000;
    8. Random random=new Random();
    9. String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
    10. try {
    11. memcachedClient.set("code",10,strCode);
    12. } catch (TimeoutException e) {
    13. e.printStackTrace();
    14. } catch (InterruptedException e) {
    15. e.printStackTrace();
    16. } catch (MemcachedException e) {
    17. e.printStackTrace();
    18. }
    19. return strCode;
    20. }
    21. @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    22. public String getCode(String code){
    23. String code1 = null;
    24. try {
    25. code1 = memcachedClient.get("code");
    26. } catch (TimeoutException e) {
    27. e.printStackTrace();
    28. } catch (InterruptedException e) {
    29. e.printStackTrace();
    30. } catch (MemcachedException e) {
    31. e.printStackTrace();
    32. }
    33. return code1;
    34. }
    35. }

     6.controller

    1. @RestController
    2. @RequestMapping("/cache")
    3. public class XmemcacheController {
    4. @Autowired
    5. private XmemcacheService xmemcacheService;
    6. /**
    7. * 生成code
    8. * @return
    9. */
    10. @GetMapping
    11. public String createCode(){
    12. String code = xmemcacheService.createCode("");
    13. System.out.println(code);
    14. return code;
    15. }
    16. @PostMapping
    17. public String getCode(){
    18. String code = xmemcacheService.getCode("");
    19. return code;
    20. }
    21. }

    7.引导类

    1. @SpringBootApplication
    2. @EnableCaching//
    3. public class Demo9SpringbootMemcacheApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(Demo9SpringbootMemcacheApplication.class, args);
    6. }
    7. }

    总结

    1.    memcached安装后需要启动对应服务才可以对外提供缓存功能,安装memcached服务需要基于windows系统管理员权限
    2.    由于springboot没有提供对memcached的缓存整合⽅案,需要采⽤⼿⼯编码的形式创建xmemcached客户端操作缓存
    3.    导⼊xmemcached坐标后,创建memcached配置类,注册MemcachedClient对应的bean,⽤于操作缓存
    4.    初始化MemcachedClient对象所需要使⽤的属性可以通过⾃定义配置属性类的形式加载

  • 相关阅读:
    【C++】Linux下如何查看opencv的版本
    第4.2关 标准输入输出——大连交通大学
    echarts入门图表可视化(基本介绍+示例代码)
    Mybatis如何使用分页插件pageHelper
    吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)
    http:strict-origin-when-cross-origin报错解决方案
    算法提升②
    [CISCN2019 总决赛 Day2 Web1]Easyweb
    Node.js安装使用问题
    redis学习(二)——redis常见命令及基础数据类型
  • 原文地址:https://blog.csdn.net/m0_62520968/article/details/126732353