• SpringBoot使用缓存


    前言

    我们都知道,一个程序的瓶颈通常都在数据库,很多场景需要获取相同的数据。比如网站页面数据等,需要一次次的请求数据库,导致大部分时间都浪费在数据库查询和方法调用上,这时就可以利用到缓存来缓解这个问题。

    简介

    本文来介绍SpringBoot来简单整合缓存,使用SpringBoot+JPA+mysql来进行数据库操作。整合JPA的文章,具体可以参考 传送门

    新建项目

    创建一个项目,pom文件中加入spring-boot-starter-cache依赖,完整pom如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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>com.dalaoyang</groupId>
        <artifactId>springboot_cache</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springboot_cache</name>
        <description>springboot_cache</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.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-cache</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    

    配置文件如下,和整合JPA一样,没有做任何修改:

    ##端口号
    server.port=8888
    
    
    
    ##数据库配置
    ##数据库地址
    spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false
    ##数据库用户名
    spring.datasource.username=root
    ##数据库密码
    spring.datasource.password=root
    ##数据库驱动
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    
    ##validate  加载hibernate时,验证创建数据库表结构
    ##create   每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
    ##create-drop        加载hibernate时创建,退出是删除表结构
    ##update                 加载hibernate自动更新数据库结构
    ##validate 启动时验证表的结构,不会创建表
    ##none  启动时不做任何操作
    spring.jpa.hibernate.ddl-auto=update
    
    ##控制台打印sql
    spring.jpa.show-sql=true
    

    实体类代码如下:

    package com.dalaoyang.entity;
    
    import javax.persistence.*;
    
    /**
     * @author dalaoyang
     * @Description
     * @project springboot_learn
     * @package com.dalaoyang.entity
     * @email yangyang@dalaoyang.cn
     * @date 2018/5/28
     */
    @Entity
    public class House {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;
        @Column(length = 10)
        private String houseName;
        private String houseSize;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getHouseName() {
            return houseName;
        }
    
        public void setHouseName(String houseName) {
            this.houseName = houseName;
        }
    
        public String getHouseSize() {
            return houseSize;
        }
    
        public void setHouseSize(String houseSize) {
            this.houseSize = houseSize;
        }
    
        public House(String houseName, String houseSize) {
            this.houseName = houseName;
            this.houseSize = houseSize;
        }
    
        public House(int id,String houseName, String houseSize) {
            this.id = id;
            this.houseName = houseName;
            this.houseSize = houseSize;
        }
    
        public House() {
        }
    }
    

    Repository如下:

    package com.dalaoyang.repository;
    
    import com.dalaoyang.entity.House;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    /**
     * @author dalaoyang
     * @Description
     * @project springboot_learn
     * @package com.dalaoyang.repository
     * @email yangyang@dalaoyang.cn
     * @date 2018/5/28
     */
    public interface HouseRepository extends JpaRepository<House,Integer> {
    }
    

    启动类上加入@EnableCaching开启缓存,完整代码如下:

    package com.dalaoyang;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @SpringBootApplication
    //开启缓存
    @EnableCaching
    public class SpringbootCacheApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(SpringbootCacheApplication.class, args);
    	}
    }
    

    还是和以往一样,使用Controller做测试,先展示一下代码:

    package com.dalaoyang.controller;
    
    import com.dalaoyang.entity.House;
    import com.dalaoyang.repository.HouseRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author dalaoyang
     * @Description
     * @project springboot_learn
     * @package com.dalaoyang.controller
     * @email yangyang@dalaoyang.cn
     * @date 2018/5/28
     */
    @RestController
    public class HouseController {
    
        @Autowired
        private HouseRepository houseRepository;
    
        //http://localhost:8888/saveHouse?id=1&houseName=别墅&houseSize=1220平方米
        @GetMapping("/saveHouse")
        @CachePut(value = "house", key = "#id")
        public House saveHouse(Integer id,String houseName,String houseSize){
            House house = new House(id,houseName, houseSize);
            houseRepository.save(house);
            return house;
        }
    
        //http://localhost:8888/queryHouse?id=1
        @GetMapping("/queryHouse")
        @Cacheable(value = "house", key = "#id")
        public House queryHouse(Integer id){
            House house = houseRepository.findOne(id);
            return house;
        }
    
        //http://localhost:8888/deleteHouse?id=1
        @GetMapping("/deleteHouse")
        @CacheEvict(value = "house", key = "#id")
        public String deleteHouse(Integer id){
            houseRepository.delete(id);
            return "success";
        }
    
        //http://localhost:8888/deleteCache
        @GetMapping("/deleteCache")
        @CacheEvict(value = "house", allEntries = true)
        public void deleteCache() {
        }
    }
    

    解释测试方法

    1.saveHouse方法

    方法中使用到了@CachePut注解,这个注解直接将返回值放入缓存中,通常用于保存和修改方法中

    2.queryHouse方法

    方法中使用到了@Cacheable注解,这个注解在执行前先查看缓存中是不是已经存在了,如果存在,直接返回。如果不存在,将方法的返回值放入缓存。

    3.deleteHouse方法

    方法中使用到了@CacheEvict注解,这个注解在执行方法执行成功后会从缓存中移除

    4.deleteCache方法

    这个方法的也是使用的@CacheEvict注解,不同的是使用了allEntries熟悉,默认为false,true的时候移除所有缓存。

    测试

    1.首先访问http://localhost:8888/saveHouse?id=1&houseName=别墅&houseSize=1220平方米,然后查看数据库和控制台,如下图:

    image

    image

    2.访问http://localhost:8888/queryHouse?id=1,查看页面数据和控制台。因为设置了打印执行jpa查询的话打印sql,看下图控制台没有打印,证明在保存的时候@CachePut注解已经将其放入了缓存中。

    image

    image

    3.调用清空缓存方法http://localhost:8888/deleteCache然后在次访问查询方法http://localhost:8888/queryHouse?id=1,查看控制台如下,可以到清空缓存后,在访问就需要查询数据库。

    image

    4.调用删除方法http://localhost:8888/deleteHouse?id=1,然后在方法查询方法http://localhost:8888/queryHouse?id=1,查看控制台如下,可以到删除缓存后,在访问也查询了数据库。

    image

    源码下载 :大老杨码云

    个人网站:https://www.dalaoyang.cn

    关注作者公众号

    dalaoyang_gongzhonghao.jpg

  • 相关阅读:
    深入了解抽象类和接口
    关于Hibernate查询对象调用set方法自动同步到数据库解决方案
    【鸽子的迷信(一)】python导入由excel文件改后缀变成的csv文件出现乱码错误(ParserError:Error tokenizing data. C error:)
    《计算机操作系统》CH1操作系统引论思维导图整理
    IntelliJ IDEA创建一个Maven项目
    C++实验三
    小练习
    C++实验二
    C++的ch1&ch2的整理
    C++实验一
  • 原文地址:https://www.cnblogs.com/dalaoyang/p/9104930.html
Copyright © 2020-2023  润新知