手记

自命为缓存之王的Caffeine(4)

您好,我是湘王,这是我的慕课手记,欢迎您来,欢迎您再来~



说了很多Caffeine的基本特性但是骡子是马终归还是要看能不能拉磨SpringBoot有两种使用Caffeine的方式:

1、直接引入Caffeine依赖,然后使用Caffeine方法实现缓存;

2、引入Caffeine和Spring Cache依赖,使用注解方式实现缓存。

先实现第一种方式(之前已实现过,整合到SpringBoot),这种方式比较灵活。再使用第二种方式(用注解实现Caffeine缓存功能),这种方式比较方便。

先引入依赖

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>


在配置文件中加入这是可选的):

## CAFFEINE
customer.caffeine.initialCapacity=50
customer.caffeine.maximumSize=500
customer.caffeine.expireAfterWrite=86400


声明注入代码:

/**
 * 声明注入代码
 *
 * @author 湘王
 */
@Configuration
@Component
public class WebConfiguration extends WebMvcConfigurationSupport {
    /**
     * 进程外缓存初始化
     *
     */
    @Bean("cache")
    public LoadingCache<String, String> cache() {
        return Caffeine.newBuilder()
                .initialCapacity(1024)
                .maximumSize(1024)
                .expireAfterWrite(1, TimeUnit.HOURS)
                .build(key -> {
                    return "";
                });
    }
}

 

然后在代码中调用

/**
 * 功能描述
 *
 * @author 湘王
 */
public class CaffeineTest {
    @Resource
    private LoadingCache<String, String> cache;

    /**
     * 保存缓存数据
     *
     */
    public void setCache(final String key, final String value) {
        cache.put(key, value);
    }

    /**
     * 读取缓存数据
     *
     */
    public String getCache(final String key) {
        return cache.get(key);
    }

    /**
     * 清除缓存数据
     *
     */
    public void clearCache(final String key) {
        cache.invalidate(key);
    }
}

 

然后再来看看第二种方式先引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>


在属性文件中加入配置

## CAFFEINE
spring.cache.cache-names=test
spring.cache.type=caffeine
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=300s


定义一个实体类之前用过的类):

/**
 * 用户entity
 *
 * @author 湘王
 */
public class SysUser implements Serializable, RowMapper<SysUser> {
    private static final long serialVersionUID = -1214743110268373599L;

    private int id;
    private int bid;
    private String username;
    private String password;
    private int scope; // 0:全部,1:部门及以下,2:仅个人
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    protected Date createtime;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    protected Date updatetime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getBid() {
        return bid;
    }

    public void setBid(int bid) {
        this.bid = bid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getScope() {
        return scope;
    }

    public void setScope(int scope) {
        this.scope = scope;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public Date getUpdatetime() {
        return updatetime;
    }

    public void setUpdatetime(Date updatetime) {
        this.updatetime = updatetime;
    }

    @Override
    public SysUser mapRow(ResultSet result, int i) throws SQLException {
        SysUser user = new SysUser();

        user.setId(result.getInt("id"));
        user.setUsername(result.getString("username"));
        user.setPassword(result.getString("password"));
        user.setCreatetime(result.getTimestamp("createtime"));
        user.setUpdatetime(result.getTimestamp("updatetime"));

        return user;
    }
}

 

然后定义服务类

/**
 * 缓存服务
 *
 * @author 湘王
 */
@Service
public class CaffeineService {
    /**
     * 将新增的用户信息放入缓存
     *
     */
    @CachePut(value = "test", key = "#id")
    public int addUser(int id, String username, String password) {
        String sql = "";
        // TODO SOMETHING
        return -1;
    }

    /**
     * 从缓存读取用户信息,id作为key
     *
     */
    @Cacheable(value = "test", key = "#id")
    public SysUser queryById(int id) {
        System.out.println("从数据库读取:" + id);
        String sql = "";
        // TODO SOMETHING
        return new SysUser();
    }

    /**
     * 从缓存读取用户信息,username作为key
     *
     */
    @Cacheable(value = "test", key = "#username")
    public SysUser queryByUsername(String username) {
        System.out.println("从数据库读取:" + username);
        String sql = "";
        // TODO SOMETHING
        return new SysUser();
    }
}

 

再定义Contorller类

/**
 * 缓存COntroller
 *
 * @author 湘王
 */
@RestController
public class CacheController {
    @Resource
    private CaffeineService caffeineService;

    /**
     * 添加用户
     *
     */
    @PostMapping("/user/add")
    public String add(int id, String username, String password) {
        caffeineService.addUser(id, username, password);
        return "添加用户成功";
    }

    /**
     * 查询用户
     *
     */
    @GetMapping("/user/id")
    public String id(int id) {
        SysUser user = caffeineService.queryById(id);
        return "查询到用户:" + user.getUsername();
    }

    /**
     * 查询用户
     *
     */
    @GetMapping("/user/username")
    public String username(String username) {
        SysUser user = caffeineService.queryByUsername(username);
        return "查询到用户:" + user.getUsername();
    }
}

 

先添加用户,再分别通过ID和用户名查询,可以看到:

1、第一次查询,会从数据库中读取;

2、第二次查询,就直接从Caffeine中读取了。

当超过设定的300s后,再次读取又会从数据中查询。

使用注解的方式简单、快速,但注解缺点是不能灵活操控,如异步存储和无法查看统计信息。



 

感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~


0人推荐
随时随地看视频
慕课网APP