springboot与缓存cache笔记

x33g5p2x  于2022-03-17 转载在 Spring  
字(9.6k)|赞(0)|评价(0)|浏览(521)

springboot与缓存cache

1.原始硬编码的方式

1.查询利用缓存

  1. 在业务层中编码:
  2. @Autowired
  3. private UserMapper userMapper;
  4. private HashMap<Integer,User> cache = new HashMap<Integer,User>();
  5. @Override
  6. public User findById(Integer id) {
  7. User user1 = cache.get(id);
  8. //如果cache中即缓存中有user1
  9. if (user1==null){
  10. User user = userMapper.selectById(id);
  11. cache.put(id,user);
  12. return user;
  13. }
  14. return user1;
  15. }

2.临时文件利用缓存

  1. @Service
  2. public class MsgServiceImpl implements MsgService {
  3. private HashMap<String,String> cache = new HashMap<>();
  4. @Override
  5. public String set(String tele) {
  6. String code = tele.substring(tele.length() - 6);
  7. return cache.put(tele,code );
  8. }
  9. @Override
  10. public boolean check(String tele, String code) {
  11. String querycode = cache.get(tele);
  12. return querycode.equals(code);
  13. }
  14. }
  15. //controller层
  16. @RestController
  17. @RequestMapping("msg")
  18. public class MsgController {
  19. @Autowired
  20. private MsgService msgService;
  21. @GetMapping("{tele}")
  22. public String set(@PathVariable String tele){
  23. return msgService.set(tele);
  24. }
  25. @PostMapping
  26. public boolean get(String tele,String code){
  27. boolean check = msgService.check(tele, code);
  28. return check;
  29. }
  30. }

2.springboot与缓存cache整合

1.临时文件的缓存

  1. 导入坐标
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-cache</artifactId>
  5. </dependency>
  6. 加入注解
  7. @EanbleCaching 在启动类上 //开启缓存功能
  8. @cacheable 在要存入缓存和读缓存的方法上加入 //操作数据结果进入缓存
  9. @cacheput 只存不读

  1. 工具类获取验证码:@Component
  2. public class SMSCodeUntiles {
  3. private String[] str = {"00000", "0000", "000", "00", "0", ""};
  4. public String generator(String tele) {
  5. //以下是电话验证码的加密
  6. int hash = tele.hashCode();
  7. int end = 2022315;
  8. long result = hash ^ end;
  9. Long nowTime = System.currentTimeMillis();
  10. result = nowTime ^ result;
  11. long code = result % 1000000;
  12. code = code > 0 ? code : -code;
  13. String codeStr = code + "";
  14. if (codeStr.length() < 6) {
  15. codeStr = str[codeStr.length() - 1] + codeStr;
  16. }
  17. return codeStr;
  18. }
  19. //从缓存中读取数据要放到spring能读取到的地方
  20. @Cacheable(value = "SMSSpace", key = "#tele")
  21. public String get(String tele) {
  22. return null;
  23. }
  1. 业务层:
  2. @Service
  3. public class SMSCodeServiceImpl implements SMSCodeService {
  4. @Autowired
  5. private SMSCodeUntiles sms;
  6. @Override
  7. @CachePut(value = "SMSSpace",key = "#tele")//将操作结果数据存入数据
  8. public String sendCodeSMS(String tele) {
  9. //获取验证码
  10. return sms.generator(tele);
  11. }
  12. //写入的验证码与生成的验证码(在缓存中)进行对比
  13. @Override
  14. public boolean checkCode(SMSCode smsCode) {
  15. String code = smsCode.getCode();
  16. //从缓存中取出数据
  17. String checkCode = sms.get(smsCode.getTele());
  18. return checkCode.equals(code);
  19. }

3.变更缓存供应商

1.Ehcache

  1. 首先导入坐标:
  2. <dependency>
  3. <groupId>net.sf.ehcache</groupId>
  4. <artifactId>ehcache</artifactId>
  5. </dependency>
  6. yml配置文件中加入
  7. spring.cache.type: ehcache //是缓存供应商有simple变成ehcache
  8. spring.ehcache.config: ehcache.xml //设置配置文件
  1. 配置文件:ehcache.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
  5. updateCheck="false">
  6. <diskStore path="D:\ehcache" />
  7. <!--默认缓存策略 -->
  8. <!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
  9. <!-- diskPersistent:是否启用磁盘持久化-->
  10. <!-- maxElementsInMemory:最大缓存数量-->
  11. <!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
  12. <!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
  13. <!-- timeToLiveSeconds:最大存活时间-->
  14. <!-- memoryStoreEvictionPolicy:缓存清除策略-->
  15. <defaultCache
  16. eternal="false"
  17. diskPersistent="false"
  18. maxElementsInMemory="1000"
  19. overflowToDisk="false"
  20. timeToIdleSeconds="60"
  21. timeToLiveSeconds="60"
  22. memoryStoreEvictionPolicy="LRU" />
  23. <cache
  24. name="smsCode"
  25. eternal="false"
  26. diskPersistent="false"
  27. maxElementsInMemory="1000"
  28. overflowToDisk="false"
  29. timeToIdleSeconds="10"
  30. timeToLiveSeconds="10"
  31. memoryStoreEvictionPolicy="LRU" />
  32. </ehcache>

2.Redis供应商

  1. 导入坐标:
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. spring:
  7. cache:
  8. type: ehcache
  9. ehcache:
  10. config: ehcache.xml
  11. redis:
  12. use-key-prefix: true #是否显示前缀
  13. cache-null-values: false #是否缓存空值
  14. key-prefix: aaa #设置redis中的键前缀为aaa
  15. time-to-live: 10 #设置生命周期为10秒
  16. redis:
  17. host: localhost
  18. port: 6379
  19. 当然还有很多配置...以后学习慢慢补充

3.memcached缓存供应商

  1. springbootmemcached没有整合需要使用硬编码方式实现客户端初始化管理
  2. 客户端:Xmemcached : 并发处理更好
  1. 导入坐标:
  2. <dependency>
  3. <groupId>com.googlecode.xmemcached</groupId>
  4. <artifactId>xmemcached</artifactId>
  5. <version>2.4.7</version>
  6. </dependency>
  1. 进行配置:
  2. @Configuration
  3. public class MemcachedConfig {
  4. @Bean
  5. public MemcachedClient getMemcachedClient() throws IOException {
  6. MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder("localhost:11211");
  7. MemcachedClient memcachedClient =memcachedClientBuilder.build();
  8. return memcachedClient;
  9. }
  10. }
  11. 业务层代码更改:
  12. @Autowired
  13. private MemcachedClient memcachedClient;
  14. @Autowired
  15. private SMSCodeUntiles sms;
  16. //以下是memcached供应商处理
  17. @Override
  18. @CachePut(value = "SMSSpace", key = "#tele")//将操作结果数据存入数据
  19. public String sendCodeSMS(String tele) {
  20. String code = sms.generator(tele);//生成验证码
  21. try {
  22. memcachedClient.set(tele, 0, code);//将生成的验证码以tele为键值存入缓存中,0代表永不过时
  23. } catch (TimeoutException e) {
  24. e.printStackTrace();
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. } catch (MemcachedException e) {
  28. e.printStackTrace();
  29. }
  30. return code;
  31. }
  32. @Override
  33. public boolean checkCode(SMSCode smsCode) {
  34. String code = null;
  35. try {
  36. code = memcachedClient.get(smsCode.getTele().toString());//根据电话从缓存中获取中
  37. } catch (TimeoutException e) {
  38. e.printStackTrace();
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. } catch (MemcachedException e) {
  42. e.printStackTrace();
  43. }
  44. //获取输入的验证码
  45. String checkCode = smsCode.getCode();
  46. return checkCode.equals(code);
  47. }

4.Jetcache

​ 定义:是对SpringCache进行封装,在原有的功能上实现了多级缓存,缓存统计,自动刷新,异步调用,数据报表等等…

多级缓存方案

本地缓存:(local)

​ ●LinkedHashMap

​ ●Caffeine

远程缓存:(remote)

​ ●Redis

​ ●Tair

首先要导入坐标:

  1. <dependency>
  2. <groupId>com.alicp.jetcache</groupId>
  3. <artifactId>jetcache-starter-redis</artifactId>
  4. <version>2.6.2</version>
  5. </dependency>//这个坐标springboot没有整合,所以需要导入版本号

在启动类上加入一个注解@EnableCreateCacheAnnotation 这是jetcache启用注解缓存的开关

远程缓存:(remote) 默认的缓存方式

在yml配置文件中写入:

  1. jetcache:
  2. remote:
  3. default: #默认的配置
  4. type: redis
  5. host: localhost
  6. port: 6379
  7. poolConfig: #配置必须要写,如果不写将报一个初始化错误
  8. maxTotal: 50 #最大连接数

在需要添加缓存的类中加入:

  1. @CreateCache(name = "jetcache"
  2. ,expire = 3600 //定义超时时间
  3. ,timeUnit = TimeUnit.MINUTES //定超时时间单位
  4. )
  5. private Cache<String,String> cache;

将获取的值存入到缓存中:

  1. cache.put(tele,code); //存入缓存

从缓存中取值:

  1. String code = cache.get(smsCode.getTele()); //从缓存中取出数据

重要:

  1. springboot版本>=2.6版本时则会报一个循环依赖的错误,则需要在配置文件中写入即可:
  2. spring:
  3. main:
  4. allow-circular-references: true //默认为false
本地缓存(local):linkedhashmap

在yml文件中:

  1. jetcache:
  2. local:
  3. default:
  4. type: linkedhashmap
  5. keyConvertor: fastjson #类型转换

  1. @CreateCache(name = "jetScape"
  2. ,expire = 3600 //定义超时时间
  3. ,timeUnit = TimeUnit.MINUTES //定超时时间单位
  4. ,cacheType = CacheType.LOCAL //确定使用什么缓存,使用本地缓存 默认是使用远程,本地都要缓存
  5. )
  6. private Cache<String,String> cache;
jetcache方法缓存

启用方法注解

  1. @SpringBootApplication
  2. @EnableCreateCacheAnnotation
  3. @EnableMethodCache(basePackages = "cn.itcast") //开启方法注解缓存 这两个注解是共存的
  4. public class Spring0108Jetcache2Application {
  5. public static void main(String[] args) {
  6. SpringApplication.run(Spring0108Jetcache2Application.class, args);
  7. }
  8. }

使用方法注解操作缓存

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserMapper userMapper;
  5. @Cached(name = "book",key = "#id",expire = 3600,timeUnit = TimeUnit.MINUTES
  6. ,cacheType = CacheType.REMOTE
  7. )
  8. @CacheRefresh(refresh = 10) //经过一段时间后刷新一次缓存
  9. @Override
  10. public User findById(Integer id) {
  11. User user = userMapper.selectById(id);
  12. return user;
  13. }
  14. @CacheUpdate(name = "user_",key = "#user.id",value="#user") //一旦更新之后就会把更新的数据放入到内存中
  15. @Override
  16. public boolean update(User user) {
  17. return userMapper.updateById(user) > 0;
  18. }
  19. @CacheInvalidate(name = "user_",key = "#id")
  20. @Override
  21. public boolean delete(Integer id) {
  22. return userMapper.deleteById(id) > 0;
  23. }

缓存对象必须保证可序列化

  1. public class User implements Serializable //实现序列化功能

  1. jetcache:
  2. statIntervalMinutes: 1 #查看缓存统计报告 1min
  3. remote:
  4. default: #默认的配置
  5. type: redis
  6. host: localhost
  7. port: 6379
  8. keyConvertor: fastjson
  9. valueEncode: java #序列化存
  10. valueDecode: java #取得时候转换成java
  11. poolConfig: #配置必须要写
  12. maxTotal: 50 #最大连接数

5.j2cache是一个缓存框架,可以和各种缓存搭配使用,实现一级,二级缓存

redis+ehcache整合

导入坐标:

  1. <dependency>
  2. <groupId>net.oschina.j2cache</groupId>
  3. <artifactId>j2cache-core</artifactId>
  4. <version>2.8.4-release</version>
  5. </dependency>
  6. <groupId>net.oschina.j2cache</groupId>
  7. <artifactId>j2cache-spring-boot2-starter</artifactId>
  8. <version>2.8.0-release</version>
  9. </dependency>
  10. <dependency>
  11. <groupId>net.sf.ehcache</groupId>
  12. <artifactId>ehcache</artifactId>
  13. </dependency>

在yml文件中设置配置文件

  1. j2cache:
  2. config-location: j2cache.properties

在j2cache.properties中配置一级缓存,二级缓存以及一级缓存到二级缓存的发送方式(以下的配置是最简单的配置,是必不可少的,只可补充,不可删除)

  1. #一级缓存
  2. # 一级缓存使用什么技术
  3. j2cache.L1.provider_class = ehcache
  4. #设置是否启用二级缓存
  5. j2cache.l2-cache-open = false
  6. #加载ehcache的配置文件
  7. ehcache.configXml = ehcache.xml
  8. #二级缓存
  9. #配置类
  10. j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
  11. j2cache.L2.cofig_section = redis
  12. redis.host = localhost:6379
  13. #一级缓存数据如何到达二级缓存
  14. j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
  15. redis.mode = single
  16. #配置前置名
  17. redis.namespace = user_

设置使用缓存

  1. @Autowired
  2. private CacheChannel cacheChannel;
  3. @Override
  4. public String sendCodeSMS(String tele) {
  5. String code =sms.generator(tele);
  6. cacheChannel.set("sms",tele,code); //存入缓存数据
  7. return code;
  8. }
  9. @Override
  10. public boolean checkCode(SMSCode smsCode) {
  11. String code = cacheChannel.get("sms", smsCode.getCode()).asString(); //从缓存中读取,
  12. return smsCode.getCode().equals(code);
  13. }

6.总结

1.spring-cache

●simple(默认)

●ehcache(需要有一个ehcache.xml文件)

●redis

​ ●memcached

2.jetcache

3.j2cache(要有一个j2cache.properties文件)

相关文章