SpringBoot整合Redis使用Restful風格實現CRUD功能

来源:https://www.cnblogs.com/xuwujing/archive/2019/05/08/10835571.html
-Advertisement-
Play Games

前言 本篇文章主要介紹的是SpringBoot整合Redis,使用Restful風格實現的CRUD功能。 Redis 介紹 Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key value資料庫。 Redis 與其他 key value緩存產品有以下三個特點: Redis支持數據的持久 ...


前言

本篇文章主要介紹的是SpringBoot整合Redis,使用Restful風格實現的CRUD功能。

Redis 介紹

Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value資料庫。 Redis 與其他 key - value緩存產品有以下三個特點:

  • Redis支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用。
  • Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  • Redis支持數據的備份,即master-slave模式的數據備份。

更多的使用說明可以查看官方的文檔。
官方文檔: https://redis.io

SpringBoot整合Redis

說明:如果想直接獲取工程那麼可以直接跳到底部,通過鏈接下載工程代碼。

開發準備

環境要求
JDK:1.8
SpringBoot:1.5.15.RELEASE
Redis:3.2或以上。

Tips:Redis的偶數為穩定版本,奇數為非穩定版本,所以在使用的時候最好使用偶數的版本!

Reids的可以看我之前的寫的這篇文章: Redis安裝教程

首先還是Maven的相關依賴:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <fastjson>1.2.41</fastjson>
    <springboot>1.5.15.RELEASE</springboot>
  </properties>

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springboot}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <version>${springboot}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${springboot}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>${springboot}</version>
        </dependency>
  
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson}</version>
        </dependency>
  
  </dependencies>

添加了相應的maven依賴之後,我們再來查看配置。
Redis配置的說明在下麵中已經說的很詳細了,這裡就不在過多說明瞭,不過需要註意的是如果Redis是集群版的話,需要使用這個spring.redis.cluster.nodes這個配置,該配置為Redis的Host加上Port,多個之間用,逗號隔開。
application.properties的配置如下:

# Redis伺服器地址
# 單機版配置
spring.redis.host = 127.0.0.1
spring.redis.port = 6379
# redis最大重連數
redis.cluster.max-redirects=3
# Redis伺服器連接密碼(預設為空)
redis.password=
# 最大空閑數  
redis.maxIdle=5  
# 連接池的最大資料庫連接數。
redis.maxTotal=5 
# 最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示無限制。  
redis.maxWaitMillis=1000  
# 連接的最小空閑時間 預設1800000毫秒(30分鐘)  
redis.minEvictableIdleTimeMillis=300000  
# 每次釋放連接的最大數目,預設3  
redis.numTestsPerEvictionRun=3 
# 逐出掃描的時間間隔(毫秒) 如果為負數,則不運行逐出線程, 預設-1  
redis.timeBetweenEvictionRunsMillis=30000  
# 是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接並嘗試取出另一個  
redis.testOnBorrow=true  
# 在空閑時檢查有效性, 預設false  
redis.testWhileIdle=true  

代碼編寫

首先是編寫Redis的配置類,對Redis這塊進行配置。
在使用SpringBoot整合Redis的時候,SpringBoot是可以根據配置自動完成Redis的相關配置,不過為了更靈活一點,我們這邊還是手動載入一下配置,配置成自己想要的那種效果吧。
首先,配置一個Redis的連接池,使用redis.clients.jedis.JedisPoolConfig這個類來進行實現,相關的配置在代碼的註釋中說明得很詳細了,這裡就不在過多講述了;
然後,再來配置一個Redis的工廠,載入Redis的連接池配置,這裡我們也可以進行一下設置,如果Redis設置了密碼,我們就載入改密碼,否則就不進行載入。
繼而,我們再來設置數據存入Redis的序列化的方式並開啟事務。這裡也順便說下為什麼要設置序列化器,如果不設置,那麼在用實體類(未序列化)進行存儲的時候,會提示錯誤: Failed to serialize object using DefaultSerializer; 當然,也可以不設置,不過存儲的實體類必須進行序列化。
最後,我們再來實例化RedisTemplate的對象,載入上述的配置。在使用的時候,只需要使用如下的方式註入就可以使用了

@Autowired
RedisTemplate<String, Object> redisTemplate;

Redis的配置類的代碼如下:

/**
 * 
 * @Title: RedisConfig
 * @Description: redis初始化配置
 * @Version:1.0.0
 * @author pancm
 * @date 2018年6月7日
 */
@Component
public class RedisConfig {

    @Value("${redis.maxIdle}")
    private Integer maxIdle;

    @Value("${redis.maxTotal}")
    private Integer maxTotal;

    @Value("${redis.maxWaitMillis}")
    private Integer maxWaitMillis;

    @Value("${redis.minEvictableIdleTimeMillis}")
    private Integer minEvictableIdleTimeMillis;

    @Value("${redis.numTestsPerEvictionRun}")
    private Integer numTestsPerEvictionRun;

    @Value("${redis.timeBetweenEvictionRunsMillis}")
    private long timeBetweenEvictionRunsMillis;

    @Value("${redis.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${redis.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${redis.cluster.max-redirects}")
    private Integer mmaxRedirectsac;

    @Value("${redis.password}")
    private String redispwd;

    /**
     * JedisPoolConfig 連接池
     * 
     * @return
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大空閑數
        jedisPoolConfig.setMaxIdle(maxIdle);
        // 連接池的最大資料庫連接數
        jedisPoolConfig.setMaxTotal(maxTotal);
        // 最大建立連接等待時間
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 逐出連接的最小空閑時間 預設1800000毫秒(30分鐘)
        jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        // 每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 預設3
        jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
        // 逐出掃描的時間間隔(毫秒) 如果為負數,則不運行逐出線程, 預設-1
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        // 是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接並嘗試取出另一個
        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        // 在空閑時檢查有效性, 預設false
        jedisPoolConfig.setTestWhileIdle(testWhileIdle);
        return jedisPoolConfig;
    }



    
    /**
     * 配置工廠
     */
    @Bean
    public JedisConnectionFactory JedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
        if (redispwd == null || redispwd.length() == 0) {
            JedisConnectionFactory.setPassword(redispwd);
        }
        return JedisConnectionFactory;
    }

    

    /**
     * 設置數據存入 redis 的序列化方式,並開啟事務
     * 
     * @param redisTemplate
     * @param factory
     */
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        /*
         * 設置 序列化器 .
         * 如果不設置,那麼在用實體類(未序列化)進行存儲的時候,會提示錯誤: Failed to serialize object using DefaultSerializer;
         */
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // 開啟事務
        redisTemplate.setEnableTransactionSupport(true);
        // 將連接工廠設置到模板類中
        redisTemplate.setConnectionFactory(factory);
    }
    
    /**
     * 實例化 RedisTemplate 對象
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }
    
}

當然,如果自己想使用自定義的Redis工具類進行實現,那麼只需在該配置類中註冊一個Bean註入封裝一下就可以了,然後在工具類中載入一下就可以了。
配置類中添加:


    @Bean(name = "redisUtil")
    public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        return redisUtil;
    }'
    

Redis的工具類添加如下代碼:

    private RedisTemplate<String, Object> redisTemplate;

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    

使用Redis工具類示例:


    @Resource
    private RedisUtil redisUtil;
    

講完Redis的配置類之後,我們再來進行編寫相應的實體類、dao層、service層和Controller層的代碼了。
由於這塊的代碼比較簡單,而且格式和之前的項目基本類似,因此這裡我就簡單的貼下代碼了。

實體類

又是萬能的用戶表 (^▽^)

代碼如下:


public class User implements Serializable{
    private static final long serialVersionUID = 1L;
    /** 編號 */
     private int id;
     /** 姓名 */
     private String name;
     /** 年齡 */
     private int age;
     
     public User(){
     }

    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return JSONObject.toJSONString(this);
    }
}

Dao 數據層

這裡我是使用的自定義的Redis工具類,其實也就是對RedisTemplate做了二次封裝。
因為使用的是set(集合)方式存儲的,所以我這邊把用戶數據的ID作為key,用戶數據作為value了。

實現類的代碼如下:


@Repository
public class UserDaoImpl implements UserDao {

    @Resource
    private RedisUtil redisUtil;
    

    @Override
    public void addUser(User user) {
        redisUtil.set(String.valueOf(user.getId()), user.toString());
    }


    @Override
    public void updateUser(User user) {
        redisUtil.set(String.valueOf(user.getId()), user.toString());
    }


    @Override
    public void deleteUser(int id) {
        redisUtil.del(String.valueOf(id));
    }

    
    @Override
    public User findByUserId(int id) {
        String data = redisUtil.get(String.valueOf(id)).toString();
        User user = JSON.parseObject(data, User.class);
        return  user;
    }
}

Service 業務層

業務層這邊處理比較簡單,成功就返回true,失敗就返回false。

實現類的代碼如下:


@Service
public class UserServiceImpl implements UserService {   

    private  final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserDao userDao;    
    
    @Override
    public boolean addUser(User user) {
        boolean flag=false;
        try{
            userDao.addUser(user);
            flag=true;
        }catch(Exception e){
            logger.error("新增失敗!",e);
        }
        return flag;
    }

    @Override
    public boolean updateUser(User user) {
        boolean flag=false;
        try{
            userDao.updateUser(user);
            flag=true;
        }catch(Exception e){
            logger.error("修改失敗!",e);
        }
        return flag;
    }

    @Override
    public boolean deleteUser(int id) {
        boolean flag=false;
        try{
            userDao.deleteUser(id);
            flag=true;
        }catch(Exception e){
            logger.error("刪除失敗!",e);
        }
        return flag;
    }


    @Override
    public User findByUserId(int id) {
        return userDao.findByUserId(id);
    }
}

Controller 控制層

控制層這邊也比較簡單,使用Restful風格實現的CRUD功能。

代碼如下:


@RestController
@RequestMapping(value = "/api")
public class UserRestController {
    
    private  final Logger logger = LoggerFactory.getLogger(this.getClass());

    
    @Autowired
    private UserService userService;
 
    @PostMapping("/user")
    public boolean addUser(@RequestBody User user) {
        logger.info("開始新增...");
        return userService.addUser(user);
    }
    
    @PutMapping("/user")
    public boolean updateUser(@RequestBody User user) {
        logger.info("開始更新...");
        return userService.updateUser(user);
    }
    
    @DeleteMapping("/user")
    public boolean delete(@RequestParam(value = "id", required = true) int userId) {
        logger.info("開始刪除...");
        return userService.deleteUser(userId);
    }
    

    @GetMapping("/user")
    public User findByUserId(@RequestParam(value = "id", required = true) int userId) {
        logger.info("開始查詢所有數據...");
        return userService.findByUserId(userId);
    }
}

App 入口

和普通的SpringBoot項目基本一樣。

代碼如下:


@SpringBootApplication
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
        System.out.println("程式正在運行...");
    }
}

功能測試

我們成功啟動該程式之後,使用Postman工具來進行介面測試。

首先添加一條數據,使用POST方式進行請求

POST http://localhost:8180/api/user

Body參數為:

{"id":1,"name":"xuwujing","age":18}

在這裡插入圖片描述
界面返回true,表示新增成功了!

然後在進行查詢,使用GET請求。

GET http://localhost:8180/api/user?id=1

返回:

{"id":1,"name":"xuwujing","age":18}

在這裡插入圖片描述

我們再來使用RedisDesktopManager工具進行查詢看下,是否真的寫入到Redis中去了。

在這裡插入圖片描述
可以看到已經成功寫入到Redis中了。

然後我們再來更新下更新該數據,使用PUT方式請求。

PUT http://localhost:8180/api/user

這裡只是更改了下age年齡,Body參數為:

{"id":1,"name":"xuwujing","age":19}

在這裡插入圖片描述
可以看到已經成功更新了。

最後我們再來查詢一遍看下是否成功更新。

GET http://localhost:8180/api/user?id=1

返回:

{"id":1,"name":"xuwujing","age":19}

在這裡插入圖片描述
可以看到已經成功更新了。

其它

其實SpringBoot整合Redis整個項目很早之前就已經寫好並且上傳到Github了,但是一直沒有抽出時間寫篇博客講述(還有很多SpringBoot的項目也是如此),最近不是那麼的忙了,於是準備了下時間編寫本篇博文。後續個人Github上的SpringBoot項目中以後有時間的話,也會對其中的一些發表博文進行講解,不過那是以後的事了ヽ(ー_ー)ノ

關於SpringBoot整合Redis的文章就講解到這裡了,如有不妥,歡迎指正!

項目地址

SpringBoot整合Redis的項目工程地址:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-Redis

SpringBoot整個集合的地址:
https://github.com/xuwujing/springBoot-study

SpringBoot整合系列的文章

音樂推薦

原創不易,如果感覺不錯,希望給個推薦!您的支持是我寫作的最大動力!
版權聲明:
作者:虛無境
博客園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm    
個人博客出處:http://www.panchengming.com


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

-Advertisement-
Play Games
更多相關文章
  • 作者:CHAITANYA SINGH 來源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=17 運算符是表示動作的字元,例如+是表示加法的算術運算符。 Java中的運算符類型有七大類:基本算術運算符、賦值運算符、自增運算符和自減運算符、邏輯運算 ...
  • [TOC] 一、自定義通用對話框 仿照windows使用Qt實現了一個自定義通用對話框,支持左側節點擴展,右側也支持註冊自定義視窗,例如文件預覽等等,可以和中間視圖列表進行通信 支持打開、保存、另存為3種模式 支持5種預覽模式 支持前進後退操作 之前當前目錄搜索 新增文件、刪除文件 文件重命名 文件 ...
  • import java.util.Scanner; /** * 斐波那契數列的和 * @author fish shadow * 輸入兩個正整數k1,k2(保證k1<=k2)。輸出斐波那契數列的第k1項到第k2項的和。 * 測試案例: * 輸入: * 3 6 *輸出: *18 *(解釋2+3+5+8 ...
  • 今天的面試題以基礎為主,去面試Python工程師,這幾個基礎問題不能答錯 第1題:列表和元組有什麼不同? 列表和元組是Python中最常用的兩種數據結構,字典是第三種。 相同點: 都是序列 都可以存儲任何數據類型 可以通過索引訪問 語法差異 使用 創建列表,而 創建元組。 是否可變 列表是 ,而元組 ...
  • python視頻 神經網路 Tensorflow 模塊 視頻教程 (帶源碼) python視頻 神經網路 Tensorflow 模塊 視頻教程 (帶源碼) python視頻 神經網路 Tensorflow 模塊 視頻教程 (帶源碼) 所屬網站分類: 資源下載 > python視頻教程 作者:smil ...
  • 參考博文:https://www.cnblogs.com/weven/p/7252917.html 以下是我按照參考博文進行實際操作的過程,此篇只作記錄。 一、下載 1、打開官網https://www.python.org/downloads/windows/,點擊Python 2版本鏈接 2、點擊 ...
  • 前言 如果說收集演算法是記憶體回收的方法論,那麼垃圾收集器就是記憶體回收的具體實現。java虛擬機規範中對垃圾收集器應該如何實現並沒有任何規定,因此不同的廠商、不同的版本的虛擬機所提供的垃圾收集器都有可能會有很大的區別,並且一般都會提供參數供用戶根據自己的應用特點和要求組合出各個年代所使用的收集器。 相關 ...
  • 簡介 上一篇介紹了 Hystrix Dashboard 監控單體應用的例子,在生產環境中,監控的應用往往是一個集群,我們需要將每個實例的監控信息聚合起來分析,這就用到了 Turbine 工具。Turbine有一個重要的功能就是匯聚監控信息,並將匯聚到的監控信息提供給Hystrix Dashboard ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...