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</modelVersion>
  <groupId>cn.yc.springboot.cache</groupId>
  <artifactId>SprintBoot-Cache</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</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;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableAutoConfiguration
@EnableCaching
public class SpringbootCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootCacheApplication.class, args);
    }

}

 

Article.java

package com.blog.entity;

import java.io.Serializable;


public class Article implements Serializable {

    private Integer id;

    private String title;

    private String content;

    private String author;

    private String fileName;

    private Integer state;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public Integer getState() {
        return state;
    }

    public void setState(Integer state) {
        this.state = state;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }


}

 

ArticleMapper.java

package com.blog.dao;


import org.apache.ibatis.annotations.Param;

import com.blog.entity.Article;


public interface ArticleMapper {


    /**
     * 插入一篇文章
     * @param title
     * @param author
     * @param content
     * @param fileName
     * @return
     */
    public Integer addArticle(@Param("title") String  title,@Param("author")String author,
                              @Param("content")String content,@Param("fileName")String fileName);
    /**
     * 根據id獲取文章
     * @param id
     * @return
     */
    public Article getArticleById(@Param("id") Integer id);

    /**
     * 更新content
     * @param content
     */
    public Integer updateContentById(@Param("content")String content,@Param("id")Integer id);

    /**
     * 根據id刪除文章
     * @param id
     * @return
     */
    public Integer removeArticleById(@Param("id")Integer id);

    /**
     * 獲得上一次插入的id
     * @return
     */
    public Integer getLastInertId();

}

 

ArticleService.java

package com.blog.service;


import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.blog.dao.ArticleMapper;
import com.blog.entity.Article;


@Service
@CacheConfig(cacheNames = "articleCache")
public class ArticleService {

    private AtomicInteger count =new AtomicInteger(0);

    @Autowired
    private ArticleMapper articleMapper;


    /**
     * 增加一篇文章
     * @return
     */
    @CachePut()
    public 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);
        }
        return result;
    }

    /**
     * 獲取文章
     * @param id 文章id
     * @return
     */
    @Cacheable(key = "#id",unless = "#result.state==0")
    public 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);
        return artcile;
    }

    /**
     * 通過id更新內容
     *
     * @param id
     * @return
     */
    @CacheEvict(key = "#id")
    public Integer updateContentById(String contetnt, Integer id) {
        Integer result = articleMapper.updateContentById(contetnt, id);
        System.out.println("--執行更新操作id:--"+id);
        return result;
    }

    /**
     * 通過id移除文章
     * @param id
     * @return
     */
    @CacheEvict(key = "#id")
    public Integer removeArticleById(Integer id){
        final Integer result = articleMapper.removeArticleById(id);
        System.out.println("執行刪除操作,id:"+id);
        return result;
    }

}

 

ArticleController.java

package com.blog.controller;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.blog.dao.ArticleMapper;
import com.blog.entity.Article;
import com.blog.model.ResultVo;
import com.blog.service.ArticleService;


@RestController
@ComponentScan(basePackages = {"com.blog.controller", "com.blog.service"})
@MapperScan(basePackages = {"com.blog.dao"})
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @Autowired
    ArticleMapper articleMapper;

    @PostMapping("/add")
    public ResultVo addArticle(@RequestBody Article article) {

        System.out.println(article.toString());
        Integer result = articleService.addArticle(article);

        if (result >= 0) {
            return ResultVo.success(result);
        }
        return ResultVo.fail();
    }


    @GetMapping("/get")
    public ResultVo getArticle(@RequestParam("id") Integer id) {

        Article article = articleService.getArticle(id);

        if (null != article)
            return ResultVo.success(article);
        return ResultVo.fail();
    }


    /**
     * 更新一篇文章
     *
     * @param contetnt
     * @param id
     * @return
     */
    @GetMapping("/resh")
    public ResultVo update(@RequestParam("content") String contetnt, @RequestParam("id") Integer id) {
        final Integer result = articleService.updateContentById(contetnt, id);
        if (result > 0) {
            return ResultVo.success(result);
        } else {
            return ResultVo.fail();
        }
    }

    /**
     * 刪除一篇文章
     *
     * @param id
     * @return
     */
    @GetMapping("/rem")
    public ResultVo remove(@RequestParam("id") Integer id) {

        final Integer result = articleService.removeArticleById(id);
        if (result > 0) {
            return ResultVo.success(result);
        } else {
            return ResultVo.fail();
        }
    }

}

 

ResultVo.java

package com.blog.model;

import java.io.Serializable;

public class ResultVo<T> implements Serializable {

    private T data;
    private Integer code;
    private String msg;

    public static final String errorMsg = "操作失敗";

    public static final String successMsg = "操作成功";

    public ResultVo(T data) {
        this.data = data;
    }

    public ResultVo(T data, Integer code) {
        this.data = data;
        this.code = code;
    }

    public ResultVo(T data, Integer code, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

    public ResultVo(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    /**
     * 成功
     *
     * @param <T> 數據
     * @return
     */
    public static <T> ResultVo success(T data) {
        return new ResultVo<T>(data, 1, successMsg);
    }

    /**
     * 失敗
     * @param <T>
     * @return
     */
    public static <T> ResultVo fail() {
        return new ResultVo(0, errorMsg);
    }


    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.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 

 

四、運行結果

 

posted @ 2018-11-02 23:16 挑戰者V 閱讀(...) 評論(...) 編輯 收藏
耐克篮球多少钱