SpringBoot2.x【八】集成Redis缓存

SpringBoot2.x【八】集成Redis缓存

在此章,我们将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个依赖包

image

点击生成下载过来一个zip包,解压之后导入IDEA工具就可以了

项目导入开发环境

build.gradle文件和maven的pom.xml相似,可以构建项目的依赖配置文件

在IDEA初始界面点击OPEN -> 选择文件 -> 找到.gradle文件 -> 选择Open —> Open as Project

image
image
image

这里的gradle环境是本地的,很简单安装配置,gradle官网下载二进制包然后解压,环境变量配置一下就可以使用了

Spring Boot Redis Cache Gradle Dependencies

上面我们已经初始化了一个项目依赖文件build.gradle,我们也可以去手动修改然后添加或修改自己需要的依赖等

image

点击上图左上角停止下载,换成下面的国内源之后在加载gradle

build.gradle
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')
}
image
定义一个实体对象

要将数据存到redis,我们需要定义一个实体来进行交互,并需要序列化实体对象

User.java

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);
    }
}
配置 Redis Cache

使用springboot的依赖我们已经用gradle来完成,除此之外我们还要配置下:
application.yml

# Redis Config
spring:
  cache:
    type: redis
  redis:
    host: localhost
    port: 6379
    password: pass1234

基于JPA的简洁数据操作

UserRepository.java

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>  { }

开启缓存并初始化数据

在启动类增加注解@EnableCaching开启缓存
并实现CommandLineRunner接口来执行启动完成之后的任务
RedisCacheApplication.java

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());
    }
}
控制层骨架

UserController.java


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
}

现在测试缓存

当我们数据库查询出来的值要放到缓存里,用@Cacheable注解

    @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 分别两次

image

发现id为3的就走了一次方法 说明缓存成功
id为1的走了两次是因为 unless里条件成立就不会缓存到redis

更新缓存

每次当我们的数据库的值要更改,我们缓存的也要更改 ,我们可以使用 @CachePut 注解

   @CachePut(value = "users", key = "#user.id")
    @PutMapping("/update")
    public User updatePersonByID(@RequestBody User user) {
        userRepository.save(user);
        return user;
    }
image
删除缓存

当我们的数据从数据库删除,我们也要从缓存进行删除,我们可以使用 @CacheEvict 注解
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存

    @CacheEvict(value = "users", allEntries=true)
    @DeleteMapping("/{id}")
    public void deleteUserByID(@PathVariable Long id) {
        logger.info("删除用户根据ID-> {}", id);
        userRepository.deleteById(id);
    }
image
image

在redis中查看已经没有了缓存

送上redis可视化工具
redis desktop manager for windows:
下载链接 : https://github.com/cuifuan/springboot-demo/releases/download/0.9.8/rdm-0.9.8-windows.rar
redis desktop manager for mac:
下载链接:https://github.com/cuifuan/springboot-demo/releases/download/1.0/rdm.app.zip

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容