java高级开发

SpringBoot2快速入门08--cache

2018-09-12  本文已影响10人  老鼠AI大米_Java全栈

spring通过注解为我们提供了缓存功能,默认使用Ehcache,当然,也可以配置用其它的方式缓存,如redis, memcache,它主要是提高数据的查询效率。

在Spring的@Cache注解中,管理的是一个Map1<name, Map2<key, value>>的存储结构,Map1对应的是CacheManager实现,Map2对应的是Cache实现,在实现中CacheManager和Cache都可以通过配置的方式,实现不同的缓存策略,如下图:


spring-cache.png

主要应用了策略模式【面向接口,而不是面向实现】实现业务与具体实现的隔离;通过具体的不同策略实现【开闭原则】,可以方便的增加多个具体实现;业务代码只依赖接口,不依赖具体的实现【依赖倒转原则】,高层的业务模块不依赖底层的具体算法。

下面,我们通过redis实现缓存。
首先导入相关包:

compile('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.apache.commons:commons-pool2')

在主引导类上添加注解,打开缓存,如下:

@EnableCaching
@SpringBootApplication
public class Chapter08Application {

接着编写配置文件,指定缓存类型是redis(先启动本地redis服务)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xfdb?useUnicode=true&characterEncoding=UTF-8
    password: root
    username: root
  redis:
    host: 127.0.0.1
    #password:
    cache:
      type: redis #指定spring默认cache
    timeout: 1000
    database: 0  #默认有16个分片,这里配置具体使用的分片,默认是0
    lettuce:
      pool:
        max-active: 8 #最大连接数(使用负值表示没有限制) 默认 8
        max-wait: -1 #最大阻塞等待时间(使用负值表示没有限制) 默认 -1
        max-idle: 8  #最大空闲连接 默认 8
        min-idle: 0

定义vo对象,如下:

public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    private String  email;

    public User() {
    }
    public User(Long id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
...

接着定义接口,因为cache使用的是策略模式(一定要使用接口),如下:

public interface UserService {
    /**
     * 添加更新
     */
    User saveOrUpdate(User user);
    /**
     * 查询
     */
    User get(Long id);
    /**
     * 删除
     */
    void delete(Long id);
}

接着,定义一个接口实现类,模拟实现从DB读取数据,若有缓存则从缓存获取,如下:

@Service
public class UserServiceImpl implements UserService {
     //模拟db存储数据
    private static final Map<Long, User> DATABASES = new HashMap<>();
    //数据初始化
    static {
        DATABASES.put(1L, new User(1L, "jack", 22));
        DATABASES.put(2L, new User(2L, "andy", 23));
        DATABASES.put(3L, new User(3L, "mack", 24));
    }

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Cacheable(value = "user", key = "#id")
    public User get(Long id) {
        // 若缓存无数据,则会打印log,同时会将数据添加到缓存
        log.info("==============> get() ");
        return DATABASES.get(id);
    }

    @CachePut(value = "user", key = "#user.id", condition = "#user.name.length() < 10")
    public User saveOrUpdate(User user) {
        //添加或更新数据到缓存,可以设置数据的条件
        log.info("==============> saveOrUpdate() ");
        DATABASES.put(user.getId(), user);
        return user;
    }

    @CacheEvict(value = "user", key = "#id", allEntries = true, beforeInvocation = true)
    public void delete(Long id) {
        //删除缓存中数据
        log.info("===============> delete()");
        DATABASES.remove(id);
    }
}

我们可以依次调用saveOrUpdate--->get---->delete---->get,查看缓存数据,当第一次调用时,会打log,说明进入了该方法,即查了db,若缓存中有数据则get不会输出log。
学习交流,请加群:64691032

上一篇 下一篇

猜你喜欢

热点阅读