前言
我们都知道,一个程序的瓶颈通常都在数据库,很多场景需要获取相同的数据。比如网站页面数据等,需要一次次的请求数据库,导致大部分时间都浪费在数据库查询和方法调用上,这时就可以利用到缓存来缓解这个问题。
简介
本文来介绍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平方米,然后查看数据库和控制台,如下图:
2.访问http://localhost:8888/queryHouse?id=1,查看页面数据和控制台。因为设置了打印执行jpa查询的话打印sql,看下图控制台没有打印,证明在保存的时候@CachePut注解已经将其放入了缓存中。
3.调用清空缓存方法http://localhost:8888/deleteCache然后在次访问查询方法http://localhost:8888/queryHouse?id=1,查看控制台如下,可以到清空缓存后,在访问就需要查询数据库。
4.调用删除方法http://localhost:8888/deleteHouse?id=1,然后在方法查询方法http://localhost:8888/queryHouse?id=1,查看控制台如下,可以到删除缓存后,在访问也查询了数据库。
源码下载 :大老杨码云