SpringBoot日記——緩存的使用


  SpringBoot核心技術的東西基本上都有介紹過了,接下來,進階點~來說說緩存吧~

  緩存這個詞不少同學應該不會很陌生。而我們這里主要使用的就是Redis。

  客戶端第一次請求的時候是從庫里拿出我們需要的數據,但如果每次查詢都從庫里拿,就會很耗時耗能。那么使用緩存以后,我們只需要第一次從庫里拿完存到緩存中,只要不清除緩存,我們以后的請求都直接在緩存中拿數據,就會快很多很多。

  先給出幾個基礎的方法,包括Mapper/Bean/Controller,不然后邊說的東西估計有些人會很懵。

package com.oooodin.cache.bean;

public class Employee {
    
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender; //性別 1男  0女
    private Integer dId;
    
    
    public Employee() {
        super();
    }

    
    public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
        super();
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.dId = dId;
    }
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getGender() {
        return gender;
    }
    public void setGender(Integer gender) {
        this.gender = gender;
    }
    public Integer getdId() {
        return dId;
    }
    public void setdId(Integer dId) {
        this.dId = dId;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
                + dId + "]";
    }

}
bean.Employee
import com.oooodin.cache.bean.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface EmployeeMapper {

    // 查詢
    @Select("SELECT * FROM employee WHERE id = #{id}")
    public Employee getEmpById(Integer id);

    // 更新
    @Update("UPDATE employee SET lastName = #{lastName},email = #{email},gender = #{gender},d_id=#{dId} WHERE id = #{id}")
    public void updateEmp(Employee employee);

    // 刪除
    @Delete("DELETE FROM employee WHERE id = #{id}")
    public void deleteEmpById(Integer id);

    // 新增
    @Insert("INSERT INTO employee(lastName,email,genderm,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})")
    public void insertEmp(Employee employee);
}
mapper.EmployeeMapper
import com.oooodin.cache.bean.Employee;
import com.oooodin.cache.mapper.EmployeeMapper;
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.stereotype.Service;

@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 將方法結果進行緩存
     * 再要相同數據,直接從緩存中獲取,不再調用方法
     *
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "emp")
    public Employee getEmp(Integer id) {
        System.out.println("查詢" + id + "號員工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

    @CachePut(cacheNames = "emp", key = "#result.id")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

    @CacheEvict(cacheNames = "emp", key = "#id")
    public void deleteEmp(Integer id) {
        employeeMapper.deleteEmpById(id);
    }
}
service.EmployeeService
import com.oooodin.cache.bean.Employee;
import com.oooodin.cache.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/emp/{id}")
    public Employee getEmploee(@PathVariable("id") Integer id) {
        Employee emp = employeeService.getEmp(id);
        return emp;
    }

    @GetMapping("/emp")
    public Employee updateEmp(Employee employee) {
        Employee emp = employeeService.updateEmp(employee);
        return emp;
    }

    @GetMapping("/delete")
    public String deleteEmp(Integer id) {
        employeeService.deleteEmp(id);
        System.out.println("success");
        return "success to delete EMP with id =" + id.toString();
    }
}
controller.EmployeeController

 

基本注解

  我們需要了解的一些基本注解有:

    @EnableCache:開啟基於注解的緩存。通常我們放在application的主方法中

    @Cacheable:針對方法請求參數對結果進行緩存
    @CachePut:保證方法的調用/執行,以及更新緩存
    @CacheEvict:清除緩存

  難么如何來使用呢?首先,在pom.xml中添加如下:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

  這樣,我們就關聯了cache緩存。

  然后,我們創建數據,在數據庫里錄入些東西,讓我們之后可以讀取和展示數據。那么關於增刪改查的,關於mapper/bean等方法我就不在這里寫了,想了解的可以翻看前邊的文章~

  下邊是主程序的代碼,我加了一些注釋,告訴大家一些基本步驟

/**
 * 一、搭建環境
 * 1.導入數據庫文件,創建出兩個表
 * 2.創建javaBean封裝數據庫
 * 3.整合Mybatis數據源信息
 *      1.配置數據庫
 *      2.使用注解版的MyBatis
 *          1)、使用@Mapper掃描包
 *          2)、創建Service和Controller
 * 二、緩存
 *      步驟:
 *          1、開啟基於注解的緩存
 *          2、標注緩存注解即可
 *              @Cacheable
 *              @CacheEvict
 *              @CachePut
 */
@MapperScan("com.oooodin.cache.mapper")
@SpringBootApplication
@EnableCaching public class CacheApplication {

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

  

  看到了吧,上邊有個橙色的注解,那個就是開啟了緩存的注解功能,這樣我們方法中寫的緩存注解就可以被識別和使用了。例如:

  這個方法的結果就會被寫入到緩存中,我們可以啟動主程序,然后在瀏覽器中多訪問幾次,看看打印了幾次,如果只有1次,說明后邊的請求都是從緩存中獲得,而沒有運行方法去查數據庫,那么就成功了。

  http://localhost:8080/emp/1   <====用這個來查詢1號員工,並存入緩存

    @Cacheable(cacheNames = "emp")
    public Employee getEmp(Integer id) {
        System.out.println("查詢" + id + "號員工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

  繼續來看:

  這個就是將緩存數據更新的作用,同時方法也一定會運行。也就是像之前那樣多次請求的話,每次都會訪問數據庫了。那么我們為什么要用這個?

  這么說吧,當我們更新數據庫的同時,同樣更新緩存。然后我們再次請求一次。所以我們更新以后,再用上邊的地址查詢一下看看是不是有更新。

  http://localhost:8080/emp?id=1&lastName=張三&gender=2  <===這個是用來更新數據到數據庫的,同時也可以更新緩存。

    @CachePut(cacheNames = "emp")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

  誒?是不是發現更新沒問題,但是查詢發現沒變啊????

  來看這個參數:key。因為我們在查詢的那個方法中如果沒有設定key,就會默認以參數當做key值在保存。然后我們在更新的時候要對應key才行。所以(取結果的id):

  這回我們再刷新和查詢的時候就會有變化了吧~

    @CachePut(cacheNames = "emp", key = "#employee.id")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

  

  在開發過程中,我們不光是要更新,也要清除緩存,不然一直存着也會有問題的~:

  這樣,我們清除緩存名未emp中key是id的那條~,再次查詢的時候,你會發現,我們又需要查詢數據庫重新保存緩存了。

  http://localhost:8080/delete?id=1  <===刪除id是1的那條緩存

    @CacheEvict(cacheNames = "emp", key = "#id")
    public void deleteEmp(Integer id) {
        employeeMapper.deleteEmpById(id);
    }

  

  當然注解和參數,還有其他很多,我們可以去進入的jar包看一下具體的都有哪些,然后自己挨個嘗試一下。比如Caching。這里我就不詳細來說了(其實也沒說多少東西……)

  對了,這里給大家推薦一下可以學習的地方。可以搜一下 尚硅谷講的SpringBoot的搞基片(高級篇),里邊講的真的很不錯,很詳細。

  真正的教程不是視頻或者書籍,而是官方API文檔和源碼。看懂這兩個就能基本解決所有問題了,加油!

 

  下一篇文章,說一下redis我們是如何整合的吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM