天天看點

Spring Boot整合Redis實作緩存

前言

在此章,我們将 SpringBoot 內建 Redis緩存,Redis是一個開源的,基于記憶體的資料結構存儲,可以用作資料庫、緩存和消息代理,在本章僅講解緩存內建。

準備工作

目前項目工具及環境

  • 開發工具 IDEA 2020.3
  • 依賴管理 Maven
  • Spring Boot
  • JDK 1.8
  • Redis

現在去初始化一個Spring網站初始生成一個SpringBoot項目

建立項目

Spring Boot整合Redis實作緩存
Spring Boot整合Redis實作緩存
Spring Boot整合Redis實作緩存
Spring Boot整合Redis實作緩存

點選 Next 後設定項目名稱後,點選 Finish 完成建立項目

建立實體對象

要将資料存到redis,我們需要定義一個實體來進行互動,并需要序列化實體對象

User.java

package com.github.gleans.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.persistence.*;
import java.io.Serializable;

@Data
@Entity
@ToString
@NoArgsConstructor
@AllArgsConstructor
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;
}      

使用JPA的簡潔資料操作

UserRepository.java

package com.github.gleans.dao;

import com.github.gleans.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 操作資料庫
 */
@Repository
public interface UserRepository extends JpaRepository<User, Long>  {

}      

接口api代碼

UserController.java

import com.github.gleans.dao.UserRepository;
import com.github.gleans.model.User;
import lombok.extern.slf4j.Slf4j;
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.*;

import java.util.List;

@Slf4j
@RestController
public class UserController {

    private  UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Cacheable(cacheNames = "userAll")
    @GetMapping("user/all")
    public Object getUserAll() {
        return userRepository.findAll();
    }

    @Cacheable(value = "users", key = "#userId", unless = "#result.money < 10000")
    @GetMapping("user/con/{userId}")
    public Object getUserByCondition(@PathVariable Long userId) {
        return userRepository.findById(userId);
    }

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

    @CacheEvict(value = "users", allEntries=true)
    @DeleteMapping("/{id}")
    public void deleteUserByID(@PathVariable Long id) {
        List<User> userListOld =  userRepository.findAll();
        log.info("删除前:{}", userListOld.toString());
        userRepository.deleteById(id);
        List<User> userList =  userRepository.findAll();
        log.info("删除後:{}", userList.toString());
    }
}      

配置 application.yml

#Redis Config
spring:
  datasource:
    url: jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000
    driverClassName: org.h2.Driver
    username: root
    password: root
  cache:
    type: redis
  redis:
    host: localhost
    port: 6379
    password: ekko1234
  jpa:
    show-sql: true
1.      

啟動 Redis

項目根目錄, 使用docker-compose up -d 啟動 redis

Microsoft Windows [版本 10.0.17763.1339]
(c) 2018 Microsoft Corporation。保留所有權利。

C:\Users\ekko\Documents\SpringBootLearn>cd springboot-redis

C:\Users\ekko\Documents\SpringBootLearn\springboot-redis>docker-compose up -d
Creating network "springboot-redis_default" with the default driver
Creating my_redis ... done

C:\Users\ekko\Documents\SpringBootLearn\springboot-redis>      

開啟緩存并初始化資料

在啟動類增加注解@EnableCaching開啟緩存

并實作CommandLineRunner接口來執行啟動完成之後的任務

SpringBootRedisApplication.java

import com.github.gleans.dao.UserRepository;
import com.github.gleans.model.User;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
//springboot啟動時執行任務CommandLineRunner
@SpringBootApplication
//開啟緩存
@EnableCaching
public class SpringBootRedisApplication implements CommandLineRunner {

    private UserRepository userRepository;

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

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("開始初始化user ->user count ->{}", userRepository.count());
        User james = new User(1L, "James", 2000);
        User potter = new User(2L, "Potter", 4000);
        User dumbledore = new User(3L, "Dumbledore", 999999);

        userRepository.save(james);
        userRepository.save(potter);
        userRepository.save(dumbledore);
        log.info("初始化完成 資料-> {}.", userRepository.findAll());
    }
}      

新增緩存

當我們資料庫查詢出來的值要放到緩存裡,用@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 分别兩次

Spring Boot整合Redis實作緩存

發現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;
    }      
Spring Boot整合Redis實作緩存

删除緩存

當我們的資料從資料庫删除,我們也要從緩存進行删除,我們可以使用 @CacheEvict 注解

allEntries 是否清空所有緩存内容,預設為 false,如果指定為 true,則方法調用後将立即清空所有緩存

@CacheEvict(value = "users", allEntries=true)
    @DeleteMapping("/{id}")
    public void deleteUserByID(@PathVariable Long id) {
        logger.info("删除使用者根據ID-> {}", id);
        userRepository.deleteById(id);
    }      
Spring Boot整合Redis實作緩存
Spring Boot整合Redis實作緩存

邏輯腦圖

繼續閱讀