一、通过HashMap实现缓存

这种方式可以简单实现本地缓存,但是实际开发中不推荐使用,下面我们来实现一下这种方式
首先创建一个管理缓存的类

public class LocalCache {
    public static HashMap&lt;String,String&gt; cache = new HashMap<&gt;();

    static {
        String name = 1 + "-" + UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(1),name);
        System.out.println("id为"+1+"的数据添加到了缓存");
    }
}

这个类中一个静态代码块,静态代码块会在类加载时就执行我们可以这里完成对缓存初始化,决定缓存内一开始就有哪些数据
另外我们可以把这个类交给spring管理

@Component
public class LocalCache {
    public static HashMap<String,String> cache = new HashMap<>();

    static {
        String name = 1 + "-" + UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(1),name);
        System.out.println("id为"+1+"的数据添加到了缓存");
    }

    @PostConstruct
    public void init(){
        String name = 2 + "-" + UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(2),name);
        System.out.println("id为"+2+"的数据添加到了缓存");
    }
}

在把类交给spring管理后,在方法加入@PostConstruct可以使这个方法默认执行
随后我们编写一个接口测试缓存

    @RequestMapping("test")
    public String test(Long id){
        String name = LocalCache.cache.get(String.valueOf(id));
        if (name != null){
            System.out.println("缓存存在查询缓存");
            System.out.println(name);
            return name;
        }
        System.out.println("缓存中不存在,查询数据库");
        name = id + "-" + UUID.randomUUID().toString();
        System.out.println(name);
        LocalCache.cache.put(String.valueOf(id),name);
        return name;
    }

启动项目
在这里插入图片描述

我们可以看到两个初始化都被执行了,然后我们调用接口查询id为1与id为2的数据
在这里插入图片描述

查询id为3的两次
在这里插入图片描述

可以看到我们是先生成一次UUID存入hashmap,第二次查询hashmap中存在了,直接从hashmap中获得数据,如此一来我们就实现了hashmap形式的本地缓存

二、通过guava local cache实现

guava cache介绍

实际使用

首先导入依赖

		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>

编写配置文件这里我们创建一个五秒钟过期时间缓存方便测试

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class GuavaLocalCache {
    private Cache<String,String> fiveSecondCache = CacheBuilder.newBuilder()
            //设置缓存初始大小应该合理设置,后续会扩容
            .initialCapacity(10)
            //最大值
            .maximumSize(100)
            //并发数设置
            .concurrencyLevel(5)
            //缓存过期时间写入后5秒钟过期
            .expireAfterWrite(5,TimeUnit.SECONDS)
            //统计缓存命中率
            .recordStats()
            .build();

    public Cache<String, String> getFiveSecondCache() {
        return fiveSecondCache;
    }

    public void setFiveSecondCache(Cache<String, String> fiveSecondCache) {
        this.fiveSecondCache = fiveSecondCache;
    }

}

下面我们对guava cache进行简单使用,并尝试其中的命中率统计功能

	@Autowired
    private GuavaLocalCache guavaLocalCache;

	@RequestMapping("guavaTest")
    public String guavaTest(Long id){
        // 获取缓存
        Cache<String, String> fiveSecondCache = guavaLocalCache.getFiveSecondCache();
        // 从缓存中获取对象
        String nameCache = fiveSecondCache.getIfPresent(String.valueOf(id));
        // 缓存中存在
        if (nameCache != null){
            System.out.println("缓存命中:" + nameCache + ","+ getCacheStats(fiveSecondCache));
            return nameCache;
        }
        //将数据存入缓存
        System.out.println("缓存未命中,"+ getCacheStats(fiveSecondCache));
        nameCache = id + "-" + UUID.randomUUID().toString();
        fiveSecondCache.put(String.valueOf(id),nameCache);
        return nameCache;
    }

    public String getCacheStats(Cache<String, String> cache){
        CacheStats stats = cache.stats();
        return "缓存命中率:"+stats.hitRate()+"被清除缓存数:"+stats.evictionCount();
    }

首先访问一次id为1的数据,等5秒后再访问一次,然后立刻访问第三
在这里插入图片描述
可以看到缓存未命中两次,其中缓存过期删除了一次,随后在5秒内立刻访问缓存命中,缓存命中率,被清除缓存数均正确测试完成
guava cache还有许多没有测试到的功能以及各种淘汰策略和机制,各位可以尝试深入了解。

使用redis实现缓存

redis简介

Redis 是C语言开发一个开源高性能键值对的内存数据库,可以用来数据库、缓存、消息中间件场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库

具体使用

redis安装以及基本使用欢迎参考我的这两篇博客
redis的简介,Linux安装redis以及jedis的使用
redis中的数据类型以及操作

下面我们介绍springboot项目中的使用
springboot中有redisstarter我们直接引用即可

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

spring配置文件加入如下设置,这里用的是properties形式的文件host部署redis服务器ip,port端口号password密码,如果没有设置密码不填即可

spring.redis.host=
spring.redis.port=
spring.redis.password=

同样我们编写接口测试

@Autowired
    private StringRedisTemplate stringRedisTemplate;

    @RequestMapping("/redisTest")
    public String redisCacheTest(Long id){
        String name = stringRedisTemplate.opsForValue().get(String.valueOf(id));
        if (name != null){
            System.out.println("缓存中存在,查询缓存");
            System.out.println(name);
            return name;
        }
        System.out.println("缓存中不存在,查询数据库");
        name = id + "-" + UUID.randomUUID().toString();
        System.out.println(name);
        stringRedisTemplate.opsForValue().set(String.valueOf(id),name);
        return name;
    }

同样的,我们查询两次id为1和id为2的数据
在这里插入图片描述
随后我们在redis中查看
在这里插入图片描述
在这里插入图片描述
可以看到我们确实的把数据存入redis中作为缓存进行读写

原文地址:https://blog.csdn.net/qq_51383106/article/details/129720597

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_15465.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注