SpringBoot实战(十三)之缓存
什么是缓存? 引用下百度百科的解释: 缓存就是数据交换的缓冲区(又称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,找到了则直接执行,找不到的话则从内存中查找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。 因为缓存往往使用的是RAM(断电即掉的非永久性储存),所以在用完后还是会把文件送到硬盘等存储器里永久存储。电脑里最大的缓存就是内存条了,最快的是CPU上镶的L1和L2缓存,显卡的显存是给显卡运算芯片用的缓存,硬盘上也有16M或者32M的缓存。 ? 说到这你或许很疑问为什么要用缓存? 比如面对千万级数据时,对于并发量和性能是非常具有挑战性的。这时如果不采用缓存的话,你每次都要直接去数据库查,那么数据库即便是分库分表,对于性能而言也是一笔不小的开支。说到这你也许还不明白为什么用缓存。直白的讲,将你每次需要到数据库中获取的大批量数据,缓存起来,每次需要查询对应的数据时,直接去缓存里面查。当然了,这里可能还会存在一个比较大的问题,对于部分项目而言,比如广告投放项目或者是一些电商项目,数据变动相对比较大,这样会导致一个问题,就是缓存数据的实时性。这里后续会讲。今天主要讲的是SpringBoot作缓存的简单Demo,主要面向一些初学者,同时笔者也作一格小小记录。框架越往后发展,就越轻量级。想当初,搭建SSM框架,一大堆XML先不说(只要很好的管理起来,看起来也不是那么讨厌),最让人头痛的就是每次引用一些非关系型数据库或者是一些类库都要导入对应的maven依赖,这是一件很头痛的事情,因为有些时候,一些依赖之间,它们会存在一定的冲突。不过还好用maven作为依赖管理,处理冲突问题还是很不错。想到我的一位朋友,他公司用的还是动态web项目。也就是手动导入jar包,有的时候还得build path一下,想到这,我觉得还是很幸运。说的或许有些偏题了,不过最想说还是,感谢老外开发出来这个SpringBoot,因为这样让我们的开发效率更加快了。 不过,就国内而言,虽然也不乏有人研究SpringBoot源码,开发出对应的开发项目,比如JFinal或者是Jeecg,但是在应用方面的广度仍不及老外,离老外还是有一定的差距,不过让我高兴的是,这个差距不再是望尘莫及,而是望其项背。话不多说,源码贴起。 ? 一、导入Maven依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> modelVersion>4.0.0</groupId>cn.yc.springboot.cacheartifactId>SprintBoot-Cacheversion>0.0.1-SNAPSHOTparent> >org.springframework.boot>spring-boot-starter-parent>2.0.6.RELEASErelativePath/> <!-- lookup parent from repository --> > propertiesproject.build.sourceEncoding>UTF-8project.build.sourceEncoding.reporting.outputEncodingproject.reporting.outputEncodingjava.version>1.8java.version> dependenciesdependency> >spring-boot-starter> >spring-boot-starter-testscope>test>org.mybatis.spring.boot>mybatis-spring-boot-starter>1.3.1>mysql>mysql-connector-java>5.1.30>spring-boot-starter-webbuildpluginsplugin> >spring-boot-maven-plugin> project> ? 二、执行SQL脚本 DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(50) DEFAULT NULL,`author` varchar(50) DEFAULT NULL,`content` text,`file_name` varchar(255) DEFAULT NULL,`state` int(2) DEFAULT '1',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*Data for the table `article` */
insert into `article`(`id`,`title`,`author`,`content`,`file_name`,`state`) values (1,'三国演义','罗贯中','test1324fdsafadsfadsfa','test001',1),(2,'水浒城','施耐庵','官逼民反','test002',1);
? 三、编写对应的类(entity,dao,service及其controller和model、启动类) SpringbootCacheApplication.java package com.blog.controller; import org.springframework.boot.SpringApplication; org.springframework.boot.autoconfigure.EnableAutoConfiguration; org.springframework.boot.autoconfigure.SpringBootApplication; org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableAutoConfiguration @EnableCaching public class SpringbootCacheApplication { static void main(String[] args) { SpringApplication.run(SpringbootCacheApplication.,args); } } ? Article.java com.blog.entity; java.io.Serializable; class Article implements Serializable { private Integer id; String title; String content; String author; String fileName; Integer state; public Integer getId() { return id; } setId(Integer id) { this.id = String getTitle() { title; } setTitle(String title) { this.title = String getContent() { content; } setContent(String content) { this.content = String getFileName() { fileName; } setFileName(String fileName) { this.fileName = Integer getState() { state; } setState(Integer state) { this.state = String getAuthor() { author; } setAuthor(String author) { this.author = author; } } ? ArticleMapper.java com.blog.dao; org.apache.ibatis.annotations.Param; com.blog.entity.Article; interface ArticleMapper { /** * 插入一篇文章 * @param title * author * content * fileName * @return */ public Integer addArticle(@Param("title") String title,@Param("author")String author,@Param("content")String content,@Param("fileName")String fileName); * 根据id获取文章 * id * public Article getArticleById(@Param("id") Integer id); * 更新content * content public Integer updateContentById(@Param("content")String content,@Param("id")Integer id); * 根据id删除文章 * public Integer removeArticleById(@Param("id" * 获得上一次插入的id * Integer getLastInertId(); } ? ArticleService.java com.blog.service; java.util.concurrent.atomic.AtomicInteger; org.springframework.beans.factory.annotation.Autowired; org.springframework.cache.annotation.CacheConfig; org.springframework.cache.annotation.CacheEvict; org.springframework.cache.annotation.CachePut; org.springframework.cache.annotation.Cacheable; org.springframework.stereotype.Service; com.blog.dao.ArticleMapper; com.blog.entity.Article; @Service @CacheConfig(cacheNames = "articleCache") ArticleService { private AtomicInteger count =new AtomicInteger(0); @Autowired ArticleMapper articleMapper; * 增加一篇文章 * */ @CachePut() Integer addArticle(Article article){ Integer result = articleMapper.addArticle(article.getTitle(),article.getAuthor(),article.getContent(),article.getFileName()); if (result>0) { Integer lastInertId = articleMapper.getLastInertId(); System.out.println("--执行增加操作--id:" + lastInertId); } result; } * 获取文章 * id 文章id * @Cacheable(key = "#id",unless = "#result.state==0") Article getArticle(Integer id) { try { //模拟耗时操作 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } final Article artcile = articleMapper.getArticleById(id); System.out.println("--执行数据库查询操作"+count.incrementAndGet()+"次"+"id:"+id); artcile; } * 通过id更新内容 * * @CacheEvict(key = "#id" Integer updateContentById(String contetnt,Integer id) { Integer result = articleMapper.updateContentById(contetnt,id); System.out.println("--执行更新操作id:--"+ * 通过id移除文章 * Integer removeArticleById(Integer id){ final Integer result = articleMapper.removeArticleById(id); System.out.println("执行删除操作,id:"+ result; } } ? ArticleController.java com.blog.controller; org.mybatis.spring.annotation.MapperScan; org.springframework.context.annotation.ComponentScan; org.springframework.web.bind.annotation.GetMapping; org.springframework.web.bind.annotation.PostMapping; org.springframework.web.bind.annotation.RequestBody; org.springframework.web.bind.annotation.RequestParam; org.springframework.web.bind.annotation.RestController; com.blog.entity.Article; com.blog.model.ResultVo; com.blog.service.ArticleService; @RestController @ComponentScan(basePackages = {"com.blog.controller","com.blog.service"}) @MapperScan(basePackages = {"com.blog.dao"}) ArticleController { @Autowired ArticleService articleService; @Autowired ArticleMapper articleMapper; @PostMapping("/add" ResultVo addArticle(@RequestBody Article article) { System.out.println(article.toString()); Integer result = articleService.addArticle(article); if (result >= 0) { ResultVo.success(result); } ResultVo.fail(); } @GetMapping("/get"public ResultVo getArticle(@RequestParam("id") Integer id) { Article article = articleService.getArticle(id); if (null != article) ResultVo.success(article); ResultVo.fail(); } * 更新一篇文章 * * contetnt * @GetMapping("/resh"public ResultVo update(@RequestParam("content") String contetnt,@RequestParam("id") Integer id) { articleService.updateContentById(contetnt,id); if (result > 0 ResultVo.success(result); } else ResultVo.fail(); } } * 删除一篇文章 * * @GetMapping("/rem"public ResultVo remove(@RequestParam("id") Integer id) { articleService.removeArticleById(id); ResultVo.fail(); } } } ? ResultVo.java com.blog.model; java.io.Serializable; class ResultVo<T> T data; Integer code; String msg; final String errorMsg = "操作失败"; final String successMsg = "操作成功" ResultVo(T data) { this.data = data; } ResultVo(T data,Integer code) { data; this.code = code; } code; this.msg = msg; } ResultVo(Integer code,1)"> * 成功 * * <T> 数据 * static <T> ResultVo success(T data) { return new ResultVo<T>(data,1 * 失败 * <T> * ResultVo fail() { new ResultVo(0 T getData() { setData(T data) { Integer getCode() { setCode(Integer code) { String getMsg() { setMsg(String msg) { msg; } } ? 四、编写XML及其对应配置文件 ArticleMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.blog.dao.ArticleMapper"> <resultMap type="com.blog.entity.Article" id="articleMap"> <result column="id" property="id"/> <result column="title" property="title"/> <result column="author" property="author"/> <result column="content" property="content"/> <result column="file_name" property="fileName"/> <result column="state" property="state"></result> </resultMap> <insert id="addArticle"> INSERT INTO article (title,author,content,file_name,state) values (#{title},#{author},#{content},#{fileName},'1') </insert> <select id="getArticleById" resultMap="articleMap"> select * from article where id = #{id} </select> <update id="updateContentById"> update article set content = #{content} where id = #{id} </update> <update id="removeArticleById"> update article set state = '0' where id = #{id} </update> <select id="getLastInertId" resultType="java.lang.Integer"> select LAST_INSERT_ID() </select> </mapper> ? application.properties spring.datasource.url=jdbc:mysql:localhost:3306/test spring.datasource.username=root spring.datasource.password=1234 spring.datasource.driver-class-name=com.mysql.jdbc.Driver mybatis.mapperLocations=classpath*:mapper/*.xml ? 四、运行结果 ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |