0
点赞
收藏
分享

微信扫一扫

【WEEK5】学习目标及总结【SpringMVC+MySQL】【中文版】

minute_5 4小时前 阅读 0

Java 实现缓存的三种方式

文章目录

一、HashMap实现缓存

​ 可以实现简单的本地缓存,但是实际开发中不推荐,我们可以简单模拟一下缓存的实现,

Step-1:实现一个缓存管理类

public class LocalCache {
    public static HashMap<String,String> cache = new HashMap<>();
    
    static {
        String name = UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(1),name);
        System.out.println("id为1的数据添加到了缓存");
    }
}
// 类中有 `static` 修饰的静态代码块,当类被加载的时候就会执行,如有不懂的可以如下博客
// https://blog.csdn.net/weixin_62636014/article/details/136851287

Step-2:将缓存管理类交给 Spring 进行管理

@Component
public class LocalCache {
    public static HashMap<String,String> cache = new HashMap<>();
    
    static {
        String name = UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(1),name);
        System.out.println("id为1的数据添加到了缓存");
    }
    
    @PostConstruct
    public void init() {
        String name = UUID.randomUUID().toString();
        LocalCache.cache.put(String.valueOf(2),name);
        System.out.println("id为2的数据添加到了缓存");
    }
}

@PostConstruct 方法在 Bean初始化中的执行顺序

  • Constructor(构造方法)

  • @Autowired(依赖注入)

  • @PostConstruct (注释的初始化方法)

Step-3:编写接口测试缓存

@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("缓存中不存在,查询数据库");
    // 查询数据库操作后,queryDataName方法没有写了;
    // 大家可以自己配一下Mybatis和JDBC进行数据库查询,达到效果是从库中查出来 name;
    name = queryDataName(id);
    System.out.println(name);
    LocalCache.cache.put(String.valueOf(id),name);
    return name;
}

public String queryDataName(Long id) {
    String name = UUID.randomUUID().toString();
    return name;
}

Step-4:结果展示

​ 这个是控制台输出,每个人的随机 UUID 不一致,我这个只是一个样例

id为1的数据添加到了缓存
id为2的数据添加到了缓存
缓存中存在,查询缓存
e2eadabe-3c42-4732-b465-e085ea5faf96
缓存中不存在,查询数据库
942ffe92-454f-4046-87e5-53e8b951d2a1

二、guava local cache 实现

Step-1:导入guava 依赖

		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.3-jre</version>
        </dependency>

Step-2:使用guava创建简单缓存管理类

为了方便展示,这里面使用了5 秒的缓存保留时间。

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()
        //设置缓存初始大小,应该合理设置,后续会扩容
        .initalCapacity(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;
    }
}

Step-3:使用 guava cache,并尝试统计命中率

public class test {
    @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> cahce) {
        CacheStats stats = cache.stats();
        return "缓冲命中率:"+stats.hitRate() +" 被清除缓冲数:" + stats.evictionCount();
    }
     
}

三、使用redis实现缓存

Step-1:导入Redis 依赖

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

SpringBoot 配置文件中加入设置,我使用的是yml 形式的文件,如果没有密码的话不填就好了

  redis:
    # IP地址
    host: XXX.XXX.XXX.XXX
    # 密码
    password: XXXXXXXX
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 1
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池的最大数据库连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms

Step-2:编写测试接口

public class TestRedis{
    
    // 下面StringRedisTemplate 是一个继承自 RedisTemplate的类
    @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;
    }
}

Step-3:进行接口测试,并使用Redis DeskTop Manager 进行查看

参考文章

  1. 【java缓存、redis缓存、guava缓存】java中实现缓存的几种方式_java缓存cache-CSDN博客
  2. 一篇文章搞定 Redis 基础知识 - 知乎 (zhihu.com)
  3. Java本地缓存技术选型(Guava Cache、Caffeine、Encache) - 掘金 (juejin.cn)
  4. MemCache原理超详细解读(仅学习) - 知乎 (zhihu.com)
  5. PostConstruct注解详细使用说明及理解-CSDN博客
  6. PostConstruct (Java Platform SE 8 ) (oracle.com)
  7. Java开发利器Guava Cache之使用篇 - 掘金 (juejin.cn)
  8. Google guava 工具类的介绍和使用 - 掘金 (juejin.cn)
  9. Redis详细介绍(精简版)_redis 服务 精简-CSDN博客
  10. 初识Redis,看这一篇就够了
举报

相关推荐

0 条评论