文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot集成cache缓存的实现

2024-04-02 19:55

关注

前言

  日常开发中,缓存是解决数据库压力的一种方案,通常用于频繁查询的数据,例如新闻中的热点新闻,本文记录springboot中使用cache缓存。

  官方文档介绍:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-caching-provider-generic

工程结构

代码编写

  pom引入依赖,引入cache缓存,数据库使用mysql,ORM框架用jpa


<!--添加springdata-cache依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <!-- 引入ehcache支持 -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

        <!--添加springdata-jpa依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--添加MySQL驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

  配置文件


server.port=10010
spring.application.name=springboot-cache

spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:/ehcache.xml

  ehcache.xml


<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">

    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir"/>

    <!-- maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制 -->
    <!-- maxElementsInMemory: 在内存中缓存的element的最大数目。-->
    <!-- eternal:elements是否永久有效,如果为true,timeouts将被忽略,element将永不过期 -->
    <!-- timeToIdleSeconds:发呆秒数,发呆期间未访问缓存立即过期,当eternal为false时,这个属性才有效,0为不限制 -->
    <!-- timeToLiveSeconds:总存活秒数,当eternal为false时,这个属性才有效,0为不限制 -->
    <!-- overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
    <!-- statistics:是否收集统计信息。如果需要监控缓存使用情况,应该打开这个选项。默认为关闭(统计会影响性能)。设置statistics="true"开启统计 -->

    <!--
        默认缓存
        无过期时间,但 600 秒内无人访问缓存立即过期
    -->
    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="600"
            timeToLiveSeconds="0"
            overflowToDisk="false">
    </defaultCache>

    <!--
        xx业务缓存
        在有效的 120 秒内,如果连续 60 秒未访问缓存,则缓存失效。
        就算有访问,也只会存活 120 秒。
    -->
    <cache name="myCache"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="0"
           overflowToDisk="false">
    </cache>
</ehcache>

  先写一个套tb_user表的CRUD代码


@RestController
@RequestMapping("/tbUser/")
public class TbUserController {
    @Autowired
    private TbUserService tbUserService;

    //方便测试暂时改成GetMapping
    @GetMapping("list")
//    @PostMapping("list")
    public List<TbUser> list(TbUser entityVo) {
        return tbUserService.list(entityVo);
    }

    @GetMapping("get/{id}")
    public TbUser get(@PathVariable("id")Integer id) {
        return tbUserService.get(id);
    }

    //方便测试暂时改成GetMapping
    @GetMapping("save")
//    @PostMapping("save")
    public TbUser save(TbUser entityVo) {
        return tbUserService.save(entityVo);
    }

    @GetMapping("delete/{id}")
    public Integer delete( @PathVariable("id") Integer id) {
        return tbUserService.delete(id);
    }
}

  opjo实体类要实现序列化


@Entity
@Table(name = "tb_user")
@Data
public class TbUser implements Serializable {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;//表id

    private String username;//用户名

    private String password;//密码

    private Date created;//创建时间

    private Integer descriptionId;//关联详情id
}

  serviceImpl中,使用注解来开启缓存


@Service
@Transactional
@CacheConfig(cacheNames = {"myCache"})
public class TbUserServiceImpl implements TbUserService{

    @PersistenceContext
    private EntityManager em;

    @Autowired
    private TbUserRepository tbUserRepository;

    //@Cacheable缓存数据:key为userList,value为返回值List<TbUser>
    @Cacheable(key = "'userList'")
    @Override
    public List<TbUser> list(TbUser entityVo) {
        System.out.println("获取list用户列表缓存数据,"+new Date());
        return tbUserRepository.findAll(Example.of(entityVo));
    }

    //@Cacheable缓存数据:key为参数id,value为返回值TbUser
    @Cacheable(key = "#id")
    @Override
    public TbUser get(Integer id) {
        System.out.println("获取数据缓存,key:"+id);
        Optional<TbUser> optionalE = tbUserRepository.findById(id);
        if (!optionalE.isPresent()) {
            throw new RuntimeException("ID不存在!");
        }
        return optionalE.get();
    }

    //@CachePut缓存新增的或更新的数据到缓存,其中缓存的名称为people,数据的key是person的id
    @CachePut(key = "#entityVo.id")
    // @CacheEvict从缓存中删除key为参数userList的数据
    @CacheEvict(key = "'userList'")
    @Override
    public TbUser save(TbUser entityVo) {
        System.out.println("新增/更新缓存,key:"+entityVo.getId());
        //entityVo传啥存啥,会全部更新
        return tbUserRepository.save(entityVo);
    }

    //清空所有缓存
    @CacheEvict(allEntries=true)
    @Override
    public Integer delete(Integer id) {
        System.out.println("清空所有缓存");
        tbUserRepository.deleteById(id);
        return id;
    }
}

  效果演示

  http://localhost:10010/tbUser/save?id=2&username=李四

  调用save方法,key为2,value为当前tbUser对象的数据被缓存下来

  http://localhost:10010/tbUser/get/2

  当我们调用get方法时,直接获取缓存数据,控制台啥也不打印,连serviceImpl的get方法都不进去(可以打断点调试)

  http://localhost:10010/tbUser/save?id=2&username=王五

  当我们再次调用save方法更新username时,缓存数据也被更新

  http://localhost:10010/tbUser/get/2

  再次调用get接口,直接返回缓存数据,后台也是方法都不进去,啥也不打印

  http://localhost:10010/tbUser/delete/2

  调用delete接口,删除数据,同时删除缓存

  再次调用get接口,发现缓存数据被清除,查询数据库

  http://localhost:10010/tbUser/list

  首次调用list接口,key为userList的,value为用户集合数据被缓存下来,再次调用直接返回缓存数据

  当调用save接口,数据更新,删除key为userList的缓存,再次调用list时,重新查库并设置缓存

  我们配置了缓存发呆时间,当120秒内未使用该缓存,立即过期,一直用就会一直存在

  我们先同时访问两个接口list、get,list接口2分钟后再次访问,get接口不能超过2分钟是不是访问一下,结果如预期

  PS:原先使用了这个jar包,有报错


 <dependency>
      <groupId>org.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>3.8.1</version>
    </dependency> 

  后面改成用上面“代码编写”里pom中引的jnet.sf.ehcache下面的ar

后记

  缓存除了能缓解数据库压力,还能做用户登录状态控制,例如:用户登录成功后cookie中保存颁发的token令牌设置永不过期,缓存存活时间也设置永不过期,发呆时间设置1天,这样只有用户在1天内有访问缓存接口,那他就可以一直保留登录状态,直至有其他业务将token或者缓存清掉。

  springboot使用cache缓存暂时先记录到这,后续有空再进行补充。

代码开源

  代码已经开源、托管到我的GitHub、码云:

  GitHub:https://github.com/huanzi-qch/springBoot

  码云:https://gitee.com/huanzi-qch/springBoot

到此这篇关于SpringBoot集成cache缓存的实现的文章就介绍到这了,更多相关SpringBoot cache缓存内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯