SpringBoot整合redis緩存(一)

来源:https://www.cnblogs.com/lzhdonald/archive/2019/09/20/11560002.html
-Advertisement-
Play Games

準備工作 1.Linux系統 2.安裝redis(也可以安裝docker,然後再docker中裝redis,本文章就直接用Linux安裝redis做演示) redis下載地址:http://download.redis.io/releases/redis-4.0.14.tar.gz 修改redis, ...


準備工作

1.Linux系統

2.安裝redis(也可以安裝docker,然後再docker中裝redis,本文章就直接用Linux安裝redis做演示)

  redis下載地址:http://download.redis.io/releases/redis-4.0.14.tar.gz

修改redis,開啟遠程訪問

找到redis中的redis.conf文件並編輯(在安裝路徑中找到)

vim ./redis.conf

1、找到bind 127.0.0.1並註釋掉

  預設127.0.0.1只能本地訪問,註釋掉即可ip訪問

2、修改 protected-mode 屬性值為no

  註釋掉並把保護模式禁用以後可以IP訪問

3、修改daemonize屬性將no 改為yes

  將daemonize設置為yes即啟動後臺運行

4、開放6379埠

/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

  預設不對外開放6379

5、啟動redis

redis-server /myconf/redis.conf

  redis-server預設在/usr/local/bin路徑下,redis.conf在redis的安裝路徑下

6、測試連接

redis-cli -h 192.168.126.129 -p 6379

  redis-cli -h redis伺服器IP -p 6379 -a 密碼(沒有設置redis密碼不要寫空,否則報錯)

 Java代碼編寫

 目錄結構

項目源碼結構

一個user表

 

 

 代碼

pom.xml文件(可以根據自己的需要來添加或修改)

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

        <!-- mybatis 與 spring boot 2.x的整合包 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--mysql JDBC驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

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

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

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

 下麵是springboot的配置文件application.yml,配置redis(裡面都有註釋解釋)

server:
  port: 8081

#資料庫連接
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mytest_springboot_cache?useUnicode=true
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: lzh

  ## Redis 配置
  redis:
    ## Redis資料庫索引(預設為0)
    database: 0
    ## Redis伺服器地址
    host: 192.168.126.129
    ## Redis伺服器連接埠
    port: 6379
    ## Redis伺服器連接密碼(預設為空)
    password:
    jedis:
      pool:
        ## 連接池最大連接數(使用負值表示沒有限制)
        #spring.redis.pool.max-active=8
        max-active: 8
        ## 連接池最大阻塞等待時間(使用負值表示沒有限制)
        #spring.redis.pool.max-wait=-1
        max-wait: -1
        ## 連接池中的最大空閑連接
        #spring.redis.pool.max-idle=8
        max-idle: 8
        ## 連接池中的最小空閑連接
        #spring.redis.pool.min-idle=0
        min-idle: 0
    ## 連接超時時間(毫秒)
    timeout: 1200

  #將themilef的預設緩存禁用,熱載入生效
  thymeleaf:
    cache: false

  #mybatis的下劃線轉駝峰配置
  configuration:
    map-underscore-to-camel-case: true

    #另外一種列印語句的方式
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

#列印sql時的語句
logging:
  level:
    com:
      acong:
        dao: debug
  file: d:/logs/bsbdj.log

 接著是實體類,這個比較簡單就不多說了

package com.lzh.springbootstudytest.bean;

import java.io.Serializable;

/**
 * @author lzh
 * create 2019-09-18-22:32
 */
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    private int uid;
    private String userName;
    private String passWord;
    private int salary;
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    public User(int uid, String userName, String passWord, int salary) {
        super();
        this.uid = uid;
        this.userName = userName;
        this.passWord = passWord;
        this.salary = salary;
    }
    public User() {
        super();
    }
} 

  這是controller類,用於暴露介面訪問

package com.lzh.springbootstudytest.controller;

import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lzh
 * create 2019-09-18-22:36
 */
@RestController
public class TestController {

    @Autowired
    private UserService userService;

    @RequestMapping("/queryAll")
    public List<User> queryAll(){
        List<User> lists = userService.queryAll();
        return lists;
    }

    @RequestMapping("/findUserById")
    public Map<String, Object> findUserById(@RequestParam int id){
        User user = userService.findUserById(id);
        Map<String, Object> result = new HashMap<>();
        result.put("uid", user.getUid());
        result.put("uname", user.getUserName());
        result.put("pass", user.getPassWord());
        result.put("salary", user.getSalary());
        return result;
    }

    @RequestMapping("/updateUser")
    public String updateUser(){
        User user = new User();
        user.setUid(1);
        user.setUserName("cat");
        user.setPassWord("miaomiao");
        user.setSalary(4000);

        int result = userService.updateUser(user);

        if(result != 0){
            return "update user success";
        }

        return "fail";
    }

    @RequestMapping("/deleteUserById")
    public String deleteUserById(@RequestParam int id){
        int result = userService.deleteUserById(id);
        if(result != 0){
            return "delete success";
        }
        return "delete fail";
    }
}

 接著是Mapper持久層Dao,這裡主要用註解寫比較方便,也可以使用mybatis的xml配置文件寫sql語句

package com.lzh.springbootstudytest.mapper;

import com.lzh.springbootstudytest.bean.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * @author lzh
 * create 2019-09-18-22:32
 */
@Mapper
public interface UserDao {

    @Select("select * from user")
    List<User> queryAll();

    @Select("select * from user where uid = #{id}")
    User findUserById(int id);

    @Update("UPDATE USER SET username = CASE WHEN (#{userName} != NULL) AND (#{userName} != '') THEN #{userName},PASSWORD = CASE WHEN (#{passWord} != NULL) AND (#{passWord} != '') THEN #{passWord},salary = CASE WHEN (#{salary} != 0) THEN #{salary} WHERE uid = #{uid}")
    int updateUser(@Param("user") User user);

    @Delete("delete from user where uid = #{id}")
    int deleteUserById(int id);

}

 service層,這裡主要是使用redis模板來寫

package com.lzh.springbootstudytest.service;

import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.mapper.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author lzh
 * create 2019-09-18-22:33
 */
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RedisTemplate redisTemplate;

    public List<User> queryAll() {
        return userDao.queryAll();
    }

    /**
     * 獲取用戶策略:先從緩存中獲取用戶,沒有則取數據表中 數據,再將數據寫入緩存
     */
    public User findUserById(int id) {
        String key = "user_" + id;

        ValueOperations<String, User> operations = redisTemplate.opsForValue();

        //判斷redis中是否有鍵為key的緩存
        boolean hasKey = redisTemplate.hasKey(key);

        if (hasKey) {
            User user = operations.get(key);
            System.out.println("從緩存中獲得數據:"+user.getUserName());
            System.out.println("------------------------------------");
            return user;
        } else {
            User user = userDao.findUserById(id);
            System.out.println("查詢資料庫獲得數據:"+user.getUserName());
            System.out.println("------------------------------------");

            // 寫入緩存
            operations.set(key, user, 5, TimeUnit.HOURS);
            return user;
        }
    }

    /**
     * 更新用戶策略:先更新數據表,成功之後,刪除原來的緩存,再更新緩存
     */
    public int updateUser(User user) {
        ValueOperations<String, User> operations = redisTemplate.opsForValue();
        int result = userDao.updateUser(user);
        if (result != 0) {
            String key = "user_" + user.getUid();
            boolean haskey = redisTemplate.hasKey(key);
            if (haskey) {
                redisTemplate.delete(key);
                System.out.println("刪除緩存中的key-----------> " + key);
            }
            // 再將更新後的數據加入緩存
            User userNew = userDao.findUserById(user.getUid());
            if (userNew != null) {
                operations.set(key, userNew, 3, TimeUnit.HOURS);
            }
        }
        return result;
    }

    /**
     * 刪除用戶策略:刪除數據表中數據,然後刪除緩存
     */
    public int deleteUserById(int id) {
        int result = userDao.deleteUserById(id);
        String key = "user_" + id;
        if (result != 0) {
            boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey) {
                redisTemplate.delete(key);
                System.out.println("刪除了緩存中的key:" + key);
            }
        }
        return result;
    }

} 

  

  這裡主要是使用RedisTemplate來對遠程redis操作,每次訪問controller暴露的介面,首先判斷redis緩存中是否存在該數據,若不存在就從資料庫中讀取數據,然後保存到redis緩存中,當下次訪問的時候,就直接從緩存中取出來。這樣就不用每次都執行sql語句,能夠提高訪問速度。 但是在保存數據到緩存中,通過設置鍵和值和超時刪除,註意設置超時刪除緩存時間不要太長,否則會給伺服器帶來壓力。

執行spring boot的啟動類,訪問http://localhost:8081/findUserById?id=1

再次訪問http://localhost:8081/findUserById?id=1就是從緩存中獲取保存的數據


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • == 與 equals()的聯繫: ==: 我們都知道Java中 == 對用於基礎數據類型(byte, short, int, long, float, double, boolean, char)判斷時, 是直接對變數值的比較. 而對於引用類型變數則是對變數地址的比較. equals(): 我們可 ...
  • 本案例主要講解 實現分散式鎖的兩種實現方式: 實現、 實現。網上關於這方面講解太多了,Van自認為文筆沒他們好,還是用示例代碼說明。 一、 實現 該方案只考慮 單機部署的場景 1.1 加鎖 1.1.1 原理 1. : 使用 來當鎖,因為 是唯一的; 1. : 我傳的是唯一值( ),很多童鞋可能不明白 ...
  • 2019-09-20-23:24:15 今天逛論壇、逛知識星球時、逛b站up主時,都說到低學歷,非科班的人最好不要去自學Python 他們都說:如果我們學python是為了找工作,最好不要把python作為主要編程語言, 因為python的主流方向都要求比較高,不適合我這種低學歷,非科班生的人學 學 ...
  • 1,下載anaconda 安裝 2,配置環境變數 anaconda3/Scripts anaconda3/Library/bin anaconda3/library/mingw-64/bin 此時配置完成 操作時主要是用 scripts下的conda.exe 註意:執行命令例如: conda lis ...
  • 之前,我做了一個實訓的項目,但是一直沒有展示如何做的,現在就讓我講解一下如何用django+bootstrap4+mysql實現這個智慧交通系統。這裡用到的是網頁的bootstrap4框架和mysql資料庫。 一:軟體項目內容 1.實訓項目簡介 智慧交通系統是旨在提高員工的日常工作便捷性、工作效率, ...
  • 最近一個月都在弄某某交易所,讓之前學的東西能夠用上,在這裡分享一下收貨的東西吧 #### 簡介 系統是進行了二次開發,用的是ZTuo開源框架第一個版本,節省了很多時間(坑也挺多,哈哈哈),文章結尾貼源碼鏈接 ,在這裡說一聲謝謝您們的付出。首先來張我自己畫的架構圖(獻醜了) ![file](https ...
  • 之前有一些人問我java怎麼學?其實我第一個建議是:“敲代碼!敲代碼!不光要看,更要乾!”,很多人光看不練,視頻收藏了一堆,就是不看,或者看了一堆視頻,就是不敲。這種學習方式:沒用!只有你敲了代碼之後,這個內容才是你的。 當你學編程的時候,要看看你的鍵盤,以敲壞鍵盤為人生目標!什麼時候你通過敲代碼把 ...
  • 簡潔易用的C++11網路庫,From:https://github.com/yedf/handy 在整理過去的資料過程中,發現過去有關註過這一個網路庫,簡單看了一下屬於輕量級的實現,因此本文將對該庫進行簡單的學習之旅,目標是對網路基礎知識進一步鞏固。 編譯和運行 庫目前實現了linux和mac環境, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...