Spring全家桶——SpringBoot2集成Redis缓存
Spring Boot Redis Cache
在此章,我们将SpringBoot2.x集成Redis Cache,Redis是一个开源的,基于内存的数据结构存储,可以用作数据库、缓存和消息代理,在本章仅讲解缓存集成。
准备工作
当前项目工具及环境
- 开发工具 IDEA 2018.3
- 依赖管理 Gradle 5.0
- JDK 1.8
- Redis
现在去初始化一个Spring网站初始生成一个SpringBoot项目
Spring Boot Redis 项目生成
进入网站 https://start.spring.io/
我们现在使用SPRING INITIALIZR
工具生成一个初始化项目,在这里我们初始了4个依赖包

点击生成下载过来一个zip包,解压之后导入IDEA工具就可以了
项目导入开发环境
build.gradle文件和maven的pom.xml相似,可以构建项目的依赖配置文件
在IDEA初始界面点击OPEN -> 选择文件 -> 找到.gradle文件 -> 选择Open —> Open as Project



这里的gradle环境是本地的,很简单安装配置,gradle官网下载二进制包然后解压,环境变量配置一下就可以使用了
Spring Boot Redis Cache Gradle Dependencies
上面我们已经初始化了一个项目依赖文件build.gradle,我们也可以去手动修改然后添加或修改自己需要的依赖等

点击上图左上角停止下载,换成下面的国内源之后在加载gradle
build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
buildscript { ext { springBootVersion = '2.1.1.RELEASE' } repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } mavenCentral() } dependencies { implementation('org.springframework.boot:spring-boot-starter-data-jpa') implementation('org.springframework.boot:spring-boot-starter-data-redis') implementation('org.springframework.boot:spring-boot-starter-web') runtimeOnly('com.h2database:h2') testImplementation('org.springframework.boot:spring-boot-starter-test') } |
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-data-redis')
implementation('org.springframework.boot:spring-boot-starter-web')
runtimeOnly('com.h2database:h2')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}

定义一个实体对象
要将数据存到redis,我们需要定义一个实体来进行交互,并需要序列化实体对象
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.example.rediscache.model; import javax.persistence.*; import java.io.Serializable; @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN") private Long id; private String name; private long money; public User() { } public User(String name, long money) { this.name = name; this.money = money; } //省略Getter 和 Setter @Override public String toString() { return String.format("User{id=%d, name='%s', money=%d}", id, name, money); } } |
import javax.persistence.*;
import java.io.Serializable;
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN")
private Long id;
private String name;
private long money;
public User() {
}
public User(String name, long money) {
this.name = name;
this.money = money;
}
//省略Getter 和 Setter
@Override
public String toString() {
return String.format("User{id=%d, name='%s', money=%d}", id, name, money);
}
}
配置 Redis Cache
使用springboot的依赖我们已经用gradle来完成,除此之外我们还要配置下:
application.yml
1 2 3 4 5 6 7 8 |
# Redis Config
spring:
cache:
type: redis
redis:
host: localhost
port: 6379
password: pass1234
|
基于JPA的简洁数据操作
UserRepository.java
1 2 3 4 5 6 7 8 |
package com.example.rediscache.repository; import com.example.rediscache.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { } |
import com.example.rediscache.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> { }
开启缓存并初始化数据
在启动类增加注解@EnableCaching
开启缓存
并实现CommandLineRunner接口来执行启动完成之后的任务
RedisCacheApplication.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.example.rediscache; import com.example.rediscache.model.User; import com.example.rediscache.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; //springboot启动时执行任务CommandLineRunner @SpringBootApplication //开启缓存 @EnableCaching public class RedisCacheApplication implements CommandLineRunner { private final UserRepository userRepository; private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired public RedisCacheApplication(UserRepository userRepository) { this.userRepository = userRepository; } public static void main(String[] args) { SpringApplication.run(RedisCacheApplication.class, args); } @Override public void run(String... args) throws Exception { logger.info("开始初始化user ->user count ->{}",userRepository.count()); User james = new User("James", 2000); User potter = new User("Potter", 4000); User dumbledore = new User("Dumbledore", 999999); userRepository.save(james); userRepository.save(potter); userRepository.save(dumbledore); logger.info("初始化完成 数据-> {}.", userRepository.findAll()); } } |
import com.example.rediscache.model.User;
import com.example.rediscache.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
//springboot启动时执行任务CommandLineRunner
@SpringBootApplication
//开启缓存
@EnableCaching
public class RedisCacheApplication implements CommandLineRunner {
private final UserRepository userRepository;
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
public RedisCacheApplication(UserRepository userRepository) {
this.userRepository = userRepository;
}
public static void main(String[] args) {
SpringApplication.run(RedisCacheApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
logger.info("开始初始化user ->user count ->{}",userRepository.count());
User james = new User("James", 2000);
User potter = new User("Potter", 4000);
User dumbledore = new User("Dumbledore", 999999);
userRepository.save(james);
userRepository.save(potter);
userRepository.save(dumbledore);
logger.info("初始化完成 数据-> {}.", userRepository.findAll());
}
}
控制层骨架
UserController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.example.rediscache.controller; import com.example.rediscache.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.*; @RestController public class UserController { private final Logger logger = LoggerFactory.getLogger(getClass()); private final UserRepository userRepository; @Autowired public UserController(UserRepository userRepository) { this.userRepository = userRepository; } //...dosomething } |
import com.example.rediscache.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
//...dosomething
}
现在测试缓存
当我们数据库查询出来的值要放到缓存里,用@Cacheable
注解
1 2 3 4 5 6 |
@Cacheable(value = "users", key = "#userId", unless = "#result.money < 10000") @RequestMapping(value = "/{userId}", method = RequestMethod.GET) public Object getUser(@PathVariable Long userId) { logger.info("获取user信息根据ID-> {}.", userId); return userRepository.findById(userId); } |
我们访问 localhost:8080/1 和 localhost:8080/3 分别两次

发现id为3的就走了一次方法 说明缓存成功
id为1的走了两次是因为 unless里条件成立就不会缓存到redis
更新缓存
每次当我们的数据库的值要更改,我们缓存的也要更改 ,我们可以使用 @CachePut 注解
1 2 3 4 5 6 |
@CachePut(value = "users", key = "#user.id") @PutMapping("/update") public User updatePersonByID(@RequestBody User user) { userRepository.save(user); return user; } |

删除缓存
当我们的数据从数据库删除,我们也要从缓存进行删除,我们可以使用 @CacheEvict
注解
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
1 2 3 4 5 6 |
@CacheEvict(value = "users", allEntries=true) @DeleteMapping("/{id}") public void deleteUserByID(@PathVariable Long id) { logger.info("删除用户根据ID-> {}", id); userRepository.deleteById(id); } |
在redis中查看已经没有了缓存
送上redis可视化工具
redis desktop manager for windows:
链接:https://pan.baidu.com/s/1tYwfM0sHLlDGDdQZc-26Sg 密码:4ivg
redis desktop manager for mac:
链接:https://pan.baidu.com/s/1g9gxtLoAtm1IA0fA5Zs0qQ 密码:aj0r