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程序中可以使⽤缓存

@SpringBootApplication
@MapperScan("com.qfedu.dao")
@EnableCaching//开启内置缓存功能
public class Demo5SpringbootExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(Demo5SpringbootExampleApplication.class, args);
    }

}

 步骤③:修改Service的实现类

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

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

        在业务⽅法上⾯使⽤注解@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

@SpringBootTest
class Demo7SpringbootRedisApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void setValue(){
        ValueOperations operations = redisTemplate.opsForValue();
        operations.set("username","zhangsanfeng");
    }

    @Test
    void getValue(){
        ValueOperations operations = redisTemplate.opsForValue();
        Object username = operations.get("username");
        System.out.println(username);
    }

    @Test
    void setHashValue() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("msg","key","aaa");
    }

    @Test
    void getHashValue() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        Object o = hashOperations.get("msg", "key");
        System.out.println(o);
    }

}

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

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

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

@SpringBootTest
class RedisTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    void setValue(){
        ValueOperations operations = stringRedisTemplate.opsForValue();
        operations.set("username","zhangsanfeng");
    }

    @Test
    void getValue(){
        ValueOperations operations = stringRedisTemplate.opsForValue();
        Object username = operations.get("username");
        System.out.println(username);
    }

    @Test
    void setHashValue() {
        HashOperations hashOperations = stringRedisTemplate.opsForHash();
        hashOperations.put("msg","key","loading");
    }

    @Test
    void getHashValue() {
        HashOperations hashOperations = stringRedisTemplate.opsForHash();
        Object o = hashOperations.get("msg", "key");
        System.out.println(o);
    }

}

 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

@RestController
@RequestMapping("/cache")
public class RedisController {

    @Autowired
    private RedisService redisService;

    /**
     * 生成code
     * @return
     */
    @GetMapping
    public String createCode(){
        String code = redisService.createCode("");
        System.out.println(code);
        return code;
    }

    @PostMapping
    public String getCode(){
        //从redis缓存中获取的,与service的返回值无关
        String code = redisService.getCode("");
        return code;
    }
}

 4.编写service

@Service
public class RedisService {

    @CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
    public String createCode(String code) {
        int max=10000;
        int min=1000;
        Random random=new Random();
        String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
        return strCode;
    }

    @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    public String getCode(String code){
        return null;
    }
}

5.在引导类打开缓存

@SpringBootApplication
@EnableCaching//打开缓存开关
public class Demo7SpringbootRedisApplication {

    public static void main(String[] args) {
        SpringApplication.run(Demo7SpringbootRedisApplication.class, args);
    }

}

总结

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



    
    

    
    
    
    
    
    
    
    
    

    

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

3.创建controller

@RestController
@RequestMapping("/cache")
public class EhcacheController {

    @Autowired
    private EhcacheService ehcacheService;

    /**
     * 生成code
     * @return
     */
    @GetMapping
    public String createCode(){
        String code = ehcacheService.createCode("");
        System.out.println(code);
        return code;
    }

    @PostMapping
    public String getCode(){
        String code = ehcacheService.getCode("");
        return code;
    }
}

4.创建service

@Service
public class EhcacheService {

    @CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
    public String createCode(String code) {
        int max=10000;
        int min=1000;
        Random random=new Random();
        String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
        return strCode;
    }

    @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    public String getCode(String code){
        return null;
    }
}

 5.修改引导类

@SpringBootApplication
@EnableCaching//
public class DemoSpringbootEhcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoSpringbootEhcacheApplication.class, args);
    }

}

总结

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.配置实体类

@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XmemcachedProperties {
    private String servers;
    private int poolSize;
    private long opTimeout;
}

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

/**
 * 该类返回⼀个客户端对象
 */
@Configuration
public class XmemcacheConfig {
    @Autowired
    private XmemcachedProperties xmemcachedProperties;

    @Bean
    public MemcachedClient getMemcachedClient(){
        MemcachedClientBuilder builder = new XMemcachedClientBuilder(xmemcachedProperties.getServers());
        builder.setConnectionPoolSize(xmemcachedProperties.getPoolSize());
        builder.setOpTimeout(xmemcachedProperties.getOpTimeout());
        MemcachedClient client = null;
        try {
            client = builder.build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return client;
    }

}

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

@Service
public class XmemcacheService {

    @Autowired
    private MemcachedClient memcachedClient;

    public String createCode(String code) {
        int max=10000;
        int min=1000;
        Random random=new Random();
        String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
        try {
            memcachedClient.set("code",10,strCode);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (MemcachedException e) {
            e.printStackTrace();
        }
        return strCode;
    }

    @Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
    public String getCode(String code){
        String code1 = null;
        try {
            code1 = memcachedClient.get("code");
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (MemcachedException e) {
            e.printStackTrace();
        }
        return code1;
    }
}

 6.controller

@RestController
@RequestMapping("/cache")
public class XmemcacheController {

    @Autowired
    private XmemcacheService xmemcacheService;

    /**
     * 生成code
     * @return
     */
    @GetMapping
    public String createCode(){
        String code = xmemcacheService.createCode("");
        System.out.println(code);
        return code;
    }

    @PostMapping
    public String getCode(){
        String code = xmemcacheService.getCode("");
        return code;
    }
}

7.引导类

@SpringBootApplication
@EnableCaching//
public class Demo9SpringbootMemcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Demo9SpringbootMemcacheApplication.class, args);
    }

}

总结

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

你可能感兴趣的:(缓存,spring,boot,java)