1、EhCache介绍
在查询数据的时候,数据大多来自于数据库,我们会基于SQL语句与数据库交互,数据库一般会基于本地磁盘IO将数据读取到内存,返回给Java服务端,我们再将数据响应给前端,做数据展示。
但是MySQL这种关系型数据库查询数据相对比较慢,因为有磁盘IO,或者是全盘扫描的风险,在针对一些热点数据时,会对MySQL造成比较大的压力,此时我们可以采用缓存的方式来解决。
而缓存又分为很多种,相对服务端角度来说,可以采用Redis和JVM这两种方式。
Redis不必多说,直接基于基于内存读写,并发读写的并发能力特别强,所以很多时间,在分布式或者微服务的项目中,为了保证数据一致性,我们会采用Redis来实现缓存。
但是在一些单体项目,我们可以采用JVM级别的缓存,比如直接采用框架自带的,例如Hibernate的缓存,MyBatis的缓存,或者是Guava提供的Cache,以及今儿要玩的EhCache。
还有一种情况可以采用JVM缓存,在分布式环境下,如果并发特别大,Redis也扛不住,这是我们可以将数据平均的分散在各个节点的JVM缓存中,并且设置一个较短的生存时间,这样就可以减缓Redis的压力,从而解决热点数据Redis扛不住的问题
同时EhCache也是Hibernate框架默认使用的缓存组件实现二级缓存。类似MyBatis,就直接用的HashMap。
2、引入EhCache
官网:http://www.ehcache.org
通过后缀就可以看出EhCache是开源的组件。
EhCache除了开源,还有可以几乎0成本和Spring整合的有点,毕竟现在Java项目大多都是基于Spring方式构建的,这也可以让我们在使用EhCache的时候更加方便。
这里还是单独的使用EhCache来感受一下,其实使用方式和HashMap的put和get的方式类似,不过EhCache提供了更加丰富的功能。
EhCache有2.x和3.x两个常用的大版本,两个版本API差异巨大,这里咱们以3.x为讲解的内容应用
官方入门文档:Ehcache 3.10 Documentation
3、复制配置文件
复制xml文件
maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="60" timeToLiveSeconds="60" overflowToDisk="false"/> maxElementsOnDisk="20000" maxElementsInMemory="2000" eternal="true" overflowToDisk="true" diskPersistent="true"/> maxElementsOnDisk="20000" maxElementsInMemory="2000" eternal="true" overflowToDisk="true" diskPersistent="true"/> 修改springmvc.xml文件 4、通过注解使用ehcache 服务接口 package com.shenmazong.zg2.service; import java.util.HashMap; /** * @author 军哥 * @version 1.0 * @description: 缓存接口 * @date 2023/10/15 19:24 */ public interface EhCacheService { public HashMap public HashMap public void delCache(String key); } 服务接口实现 package com.shenmazong.zg2.service.impl; import com.shenmazong.zg2.service.EhCacheService; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.HashMap; /** * @author 军哥 * @version 1.0 * @description: TODO * @date 2023/10/15 19:26 */ @Service @Slf4j public class EhCacheServiceImpl implements EhCacheService { @Override @Cacheable(value = "myCache", key = "'EhCacheServiceImpl'+#key") public HashMap log.info("createCache:"+key+"~~~~~"); HashMap map.put("name", "冯刚刚"); map.put("age", "18岁"); map.put(key, value); return map; } @Override @Cacheable(value = "myCache", key = "'EhCacheServiceImpl'+#key") public HashMap return null; } @Override @CacheEvict(value = "myCache", key = "'EhCacheServiceImpl'+#key") public void delCache(String key) { log.info("delCache:"+key+"~~~~~"); return; } } 缓存控制层 package com.shenmazong.zg2.controller; import com.shenmazong.zg2.service.EhCacheService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 军哥 * @version 1.0 * @description: 缓存控制类 * @date 2023/10/15 19:46 */ @RestController @RequestMapping(value = "/cache") public class EhCacheController { @Autowired EhCacheService ehCacheService; @PostMapping(value = "/create") public Object create() { return ehCacheService.createCache("name", "张飞"); } @PostMapping(value = "/get") public Object get() { return ehCacheService.getCache("name"); } @PostMapping(value = "/delete") public Object delete() { ehCacheService.delCache("name"); return "OK"; } } 删除所有缓存 @Override @CacheEvict(value = "myCache", allEntries = true) public void delCacheAll() { } 5、通过注解使用ehcache package com.shenmazong.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller @Slf4j @RequestMapping(value = "/eh") public class EhController { @Autowired EhCacheCacheManager cacheManager; /** * 放入缓存 * @param code * @return */ @GetMapping(value = "/put") @ResponseBody public Object put(@RequestParam("code") String code) { cacheManager.getCache("myCache").put("userCode", code); return "OK"; } /** * 从缓存中取数据 * @return */ @GetMapping(value = "/get") @ResponseBody public Object get() { String userCode = cacheManager.getCache("myCache").get("userCode", String.class); if(userCode != null) { System.out.println(userCode); return userCode; } return "NO DATA"; } /** * 从缓存中删除数据 * @return */ @GetMapping(value = "/del") @ResponseBody public Object del() { cacheManager.getCache("myCache").evict("userCode"); return "OK"; } /** * 删除所有缓存 * @return */ @GetMapping(value = "/delAll") public Object delAll() { cacheManager.getCache("myCache").clear(); return "OK"; } } 相关阅读 大家都在找: spring boot:springboot连接mysql数据库 缓存:缓存文件可以删除吗 后端:后端和前端有什么区别
发表评论