缓存

时间:2024-04-14 07:06:11
  • 什么是缓存

缓存是一种介于数据永久存储介质与数据应用之间的数据临时存储介质

使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能

缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间

模拟缓存

手动写一个模拟缓存的demo,这里我们在server层中模拟一个缓存

@Server
public class Bookserverimpl implements Bookserver{
@Autowired
private BookDao bookdao;
private HashMap<Integer,Book> cache=new HashMap<Integer,Book>();
public Book getById(Integer id){
Book book=cache.get(id);
if(book=null){
Book qubook=BookDao.selectById(id);
cache.put(id,qubook);
return qubook;
}
}
return cache.get(id);
}

这里面的HashMap对象充当一个缓存器,对数据库中的数据进行查询,先对缓存中进行查询,当缓存中有这个数据的时候就查询缓存中的数据,当缓存中没有的时候再在数据库中进行查询并添加到缓存器中

Spring缓存技术

SpringBoot提供了缓存技术,方便缓存使用
首先导入缓存的依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

在启动类中加入注解 @EnableCaching表示启动缓存

@SpringBootApplication
@EnableCaching
public class SpringbootApplication{
}

在服务层使用缓存技术:

@Cacheable(value="cacheSpace",key="#id")
public Book getByid(Integer id){
}

但是这里有一个问题,在这个注解中也有向外读取的操作,我们应该将注解换成 @CachePut
value属性指创建一个存储空间,其中放入key的值,#id表示可以读取名为id 的值

上述操作就是spring官方默认的缓存技术,除此之外,spring还可以整合第三方的缓存技术,统一接口,实现高效开发

第三方缓存技术

第三方缓存技术

Ehcache缓存供应

导入ehcache的依赖:

        <dependency>
            <groupId>ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>1.2</version>
        </dependency>

在配置文件中设置cache的类型启用ehcache

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

使用ehcache需要有一个其独立的配置文件,用来配置其中的设置
在这里插入图片描述
在配置文件当中缓存还可以多次进行配置,我再写一个defaultCache用name区分

<defaultCache
    name="cacac"
    ....
    />
  • 注意

当我们改换第三方技术的时候,原有的默认注解并没有进行改变,依然可以正常使用

Redis缓存

首先先导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

在配置文件中选择cache的类型为redis

  redis:
    host: localhost
    port: 6379

redis的相关配置也在配置文件中进行配置

spring:
  cache:
    type: redis
    redis:
      use-key-prefix: true   #是否使用前缀
      cache-null-values: false  #是否缓存空值
      key-prefix:  aa  #指定前缀
      time-to-live: 10s #最大活动周期

注意属性的层次尤其是redis
在这里插入图片描述

memcached缓存(国内)

下载memcached
地址:https://www.runoob.com/memcached/window-install-memcached.html
下载之后解压目录:
在管理员权限下运行cmd,进入到当前目录中输入命令安装并启动服务
在这里插入图片描述
当需要服务停止的时候输入memcached.exe -d stop

  • memcached客户端选择
  1. Memcached Client for java:最早期客户端,稳定可靠,用户群广
  2. SpyMemcached: 效率更高
  3. Xmemcached: 并发处理好

我们这里采用技术更加先进的Xmemcached技术,但是SpringBoot未提供对xmemcached的整合,需要使用硬编码方式实现客户端初始化管理

首先导入依赖:

        <dependency>
           <groupId>com.googlecode.xmemcached</groupId>
            <artifactId>xmemcached</artifactId>
            <version>2.4.7</version>
        </dependency>

写一个控制类


@Configuration
public class XmemcachedConfig {
    @Bean
    public MemcachedClient getmemcacheclient() throws IOException {
        MemcachedClientBuilder memcachedClientBuilder=new XMemcachedClientBuilder("localhost:11211");
        MemcachedClient memcachedClient=memcachedClientBuilder.build();
        return memcachedClient;
    }
}

像控制类中的配置信息还可以通过配置文件进行自定义配置:

memcached:
   servers: localhost:11211
   poolSize: 10               #连接池的最大连接数
   opTimeout: 3000

自定义文件之后配置一个对应的属性类进行配置

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

这个时候在配置类中就可以进行使用

@Configuration
public class XmemcachedConfig {
    @Bean
    public MemcachedClient getmemcacheclient() throws IOException {
        MemcachedClientBuilder memcachedClientBuilder=new XMemcachedClientBuilder(memcachedproperties.getServers());
        memcachedClientBuilder.setconnectionPoolSize(memcachedProperties.getPoolSzie());   //设置最大连接数
        memcachedClientBuilder.setOptimeout(memcachedProperties.getOpTimeout());
        MemcachedClient memcachedClient=memcachedClientBuilder.build();
        return memcachedClient;
    }
}

在服务类中注入使用

@Autowired
private MemcachedClient memcachedClient;
public String sendCodeTosms(String tele){
memcachedclient.set(tele,0,code); //第一个参数是key,第二个参数是过期时间,第三个参数是值,这句话需要try-catch抛出
}