1. 程式人生 > >Redis 入門與應用

Redis 入門與應用

目錄

一、Redis 安裝

1、下載 redis 

2、安裝 redis 

3、設定 redis

4、redis 服務常用的命令

5、測試 redis

二、RedisDesktopManager 的安裝與使用

1、下載與安裝

2、連線 redis 

三、SSM 專案中配置 Redis

1、引入 redis 的 jar 包依賴

2、配置 redis.properties

3、新建 JedisPoolWriper.java

4、新建 JedisUtil.java

5、Redis 配置檔案 spring-redis.xml

四、SSM 專案中使用 Redis

1、為什麼要用 Redis?

2、專案中使用 Redis 的原理

3、redis 的簡單實現(SSM環境)


一、Redis 安裝

1、下載 redis 

百度網盤連結: https://pan.baidu.com/s/1dY8Lwx7AsIj1cAk31SPQgQ 提取碼: fyt4

官網連結:https://redis.io/download

下載完後,直接解壓就可以了。

2、安裝 redis 

①  開啟 cmd(以管理員身份執行),通過 cd 進入到 redis 目錄下。

② 啟動命令

redis-server redis.windows.conf,出現下圖表示安裝成功。

但是,這種形式開啟,只要一關掉 cmd 視窗,redis 服務也一樣被關閉了。所以我們需要設定以下 redis ,讓它不隨 cmd 視窗的關閉而關閉。

3、設定 redis

① 開啟計算機管理下的服務,我們可以看到是沒有 Redis 服務的。

② 設定服務命令(在 Redis 目錄下執行)

redis-server --service-install redis.windows-service.conf --loglevel verbose

輸入命令之後沒有報錯,表示安裝成功。直接在服務視窗重新整理服務,會看到多了一個 Redis 服務。

4、redis 服務常用的命令

解除安裝服務:redis-server --service-uninstall

開啟服務:redis-server --service-start

停止服務:redis-server --service-stop

5、測試 redis

① 啟動 redis 服務

② 測試

二、RedisDesktopManager 的安裝與使用

1、下載與安裝

可以直接從官網下載,也可以從我上面提供的百度雲連線裡面下載。下載後,直接下一步到完成就行。

2、連線 redis 

填寫相關介面資訊,然後點選OK,連線上後,可以在 redis 中看到剛剛測試 redis 連線時新建的 key (user),以及 key 的 value 值(dong)。要知道 redis 中的資料是以 { key : value } 的形式存在的。

如果 redis 服務連線不上,就需要關閉 redis 的保護模式了。用寫字板的方式開啟 redis 目錄下的 redis.windows.conf 。找到裡面的  protexted-mode yes ,然後將 yes 改為 no 就行。

三、SSM 專案中配置 Redis

1、引入 redis 的 jar 包依賴

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
</dependency>

2、配置 redis.properties

在 jdbc.properties 同級目錄下,新建一個 redis.properties 檔案來存放 redis 服務的相關連線資訊。

redis.hostname=127.0.0.1
redis.port=6379
redis.database=0
redis.pool.maxActive=600
redis.pool.maxIdle=300
redis.pool.maxWait=3000
redis.pool.testOnBorrow=true

在載入 jdbc.properties 的時候,一起載入 redis.properties 檔案。

<context:property-placeholder location="classpath:jdbc.properties,classpath:redis.properties"/>

3、新建 JedisPoolWriper.java

JedisPoolWriper.java 是用來注入和獲取 Redis 連線 JedisPool。

package com.cache;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 強指定redis的JedisPool介面建構函式,這樣才能在centos成功建立jedispool
 */
public class JedisPoolWriper {
	/**
	 * Redis 連線池物件
	 */
	private JedisPool jedisPool;
	
	public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host,
			final int port) {
		try {
			jedisPool = new JedisPool(poolConfig, host, port);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 獲取 Redis 連線池物件
	 * @return
	 */
	public JedisPool getJedisPool() {
		return jedisPool;
	}
	/**
	 * 注入 Redis 連線池物件
	 * @param jedisPool
	 */
	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}
}

4、新建 JedisUtil.java

JedisUtil.java 是用來編寫從 Redis 服務中獲取資料或者將資料存放到 Redis 服務中的方法。

package com.cache;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.util.SafeEncoder;

public class JedisUtil {
	// 操作 Key 的方法
	public Keys KEYS;
	// 對儲存結構為 String 型別的操作
	public Strings STRINGS;
	// Redis 連線池
	private JedisPool jedisPool;

	// 獲取 redis 連線池
	public JedisPool getJedisPool() {
		return jedisPool;
	}

	// 設定 redis 連線池
	public void setJedisPool(JedisPoolWriper jedisPoolWriper) {
		this.jedisPool = jedisPoolWriper.getJedisPool();
	}

	// 從 jedis 連線池中獲取 jedis 物件
	public Jedis getJedis() {
		return jedisPool.getResource();
	}
	// *******************************************Keys*******************************************//
	public class Keys {
		/**
		 * 判斷key是否存在
		 * 
		 * @param String
		 *            key
		 * @return boolean
		 */
		public boolean exists(String key) {
			// ShardedJedis sjedis = getShardedJedis();
			Jedis sjedis = getJedis();
			boolean exis = sjedis.exists(key);
			sjedis.close();
			return exis;
		}
	}
	// *******************************************Strings*******************************************//
	public class Strings {
		/**
		 * 根據key獲取記錄
		 * 
		 * @param String
		 *            key
		 * @return 值
		 */
		public String get(String key) {
			// ShardedJedis sjedis = getShardedJedis();
			Jedis sjedis = getJedis();
			String value = sjedis.get(key);
			sjedis.close();
			return value;
		}
		/**
		 * 獲取並設定指定key對應的value<br/>
		 * 如果key存在返回之前的value,否則返回null
		 * 
		 * @param String
		 *            key
		 * @param String
		 *            value
		 * @return String 原始value或null
		 * */
		public String set(String key, String value) {
			Jedis jedis = getJedis();
			String str = jedis.getSet(key, value);
			jedis.close();
			return str;
		}

	}
}

5、Redis 配置檔案 spring-redis.xml

在 spring 的配置檔案下,新建一個 spring-redis.xml 檔案來配置 redis。

配置檔案需要修改的地方提示:class 檔案的路徑。根據自己的實際路徑去修改。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
	
	<!-- Redis 連線池的設定 -->
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<!-- 控制一個 pool 可分配多少個 jedis 例項 -->
		<property name="maxTotal" value="${redis.pool.maxActive}" />
		<!-- 連線池中最多可空閒 maxIdle 個連線,這裡取值為 20,表示即使沒有資料庫連線時依然可以保持 20 空閒的連線,而不被清楚,隨時處於待命狀態. -->
		<property name="maxIdle" value="${redis.pool.maxIdle}" />
		<!-- 最大等待時間:當沒有可用連線時,連線池等待連線被歸還的最大時間(以毫秒計數),超過時間則丟擲異常 -->
		<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
		<!-- 在獲取連線的時候檢查有效性 -->
		<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
	</bean>
	
	<!-- 建立 Redis 連線池,並做相關配置 -->
	<bean id="jedisWritePool" class="com.cache.JedisPoolWriper"
		depends-on="jedisPoolConfig">
		<constructor-arg index="0" ref="jedisPoolConfig" />
		<constructor-arg index="1" value="${redis.hostname}" />
		<constructor-arg index="2" value="${redis.port}" type="int" />
	</bean>
	
	<!-- 建立 Redis 工具類,封裝好 Redis 的連線以進行相關的操作 -->
	<bean id="jedisUtil" class="com.cache.JedisUtil"
		scope="singleton">
		<property name="jedisPool">
			<ref bean="jedisWritePool" />
		</property>
	</bean>
	
	<!-- Redis 的 Key 操作 -->
	<bean id="jedisKeys" class="com.cache.JedisUtil$Keys"
		scope="singleton">
		<constructor-arg ref="jedisUtil"></constructor-arg>
	</bean>
	
	<!-- Redis 的 String 操作 -->
	<bean id="jedisStrings" class="com.cache.JedisUtil$Strings"
		scope="singleton">
		<constructor-arg ref="jedisUtil"></constructor-arg>
	</bean>
	
</beans>

四、SSM 專案中使用 Redis

1、為什麼要用 Redis?

因為 Redis 的訪問速度比 MySql 的訪問速度快多了。所以我們一般是把一些變化不大的速度給存放到 Redis 快取裡面。

2、專案中使用 Redis 的原理

獲取資料的時候,先從 redis 中獲取,如果 redis 中並沒有需要用到的資料,則直接從資料庫中獲取相關的資料返回,並將獲取的資料存放到 redis 中。下一次獲取資料的時候,就能從 redis 中獲取到了。然後資料有更新、插入、刪除的時候,也要同步更新到 redis 中。

tip:當資料有變化時,可以直接把 redis 上的 key 給刪除掉。就不會造成下次獲取的資料是沒變化前的資料。

3、redis 的簡單實現(SSM環境)

現在假設我專案有一張分類表,表中的資料基本都不會有很大的變化,所以我要把表中的資料給存放 redis 服務中。實現的方法就是在 service 層中去判斷 redis 服務中是否存在相關的 key ,如果存中,就直接從 redis 中獲取資料;如果不存在,就從資料庫中獲取,在返回資料的同時,將資料設定存進 redis 中。

具體的程式碼實現如下:

import java.io.IOException;
        import java.util.ArrayList;
        import java.util.List;

        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Service;

        import com.cache.JedisUtil;
        import com.dao.AreaDao;
        import com.fasterxml.jackson.core.JsonParseException;
        import com.fasterxml.jackson.core.JsonProcessingException;
        import com.fasterxml.jackson.databind.JavaType;
        import com.fasterxml.jackson.databind.JsonMappingException;
        import com.fasterxml.jackson.databind.ObjectMapper;
        import com.pojo.Area;
        import com.service.AreaService;

@Service
public class AreaServiceImpl implements AreaService {
    @Autowired
    private AreaDao areaDao;

    @Autowired
    private JedisUtil.Keys jedisKeys;

    @Autowired
    private JedisUtil.Strings jedisStrings;

    private static String AREALISTKEY = "arealist";

    @Override
    public List<Area> getAreaList(){
        String key = AREALISTKEY;
        List<Area> areaList = null;
        ObjectMapper mapper = new ObjectMapper();
        // 判斷 redis 服務中是否存在相關的 key 
        if( !jedisKeys.exists(key) ){
            areaList = areaDao.queryArea();
            String jsonString = null;
            try {
                jsonString = mapper.writeValueAsString(areaList);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                System.out.println("異常:"+e.getMessage());
            }
            jedisStrings.set(key,jsonString);
            System.out.println("從資料庫中獲取資料");
        }else{
            String jsonString = jedisStrings.get(key);
            // 引數 Area.class 為需要獲取到資料的實體類
            JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, Area.class);
            try {
                areaList = mapper.readValue(jsonString, javaType);
            } catch (JsonParseException e) {
                e.printStackTrace();
                System.out.println("異常 JsonParseException:"+e.getMessage());
            } catch (JsonMappingException e) {
                e.printStackTrace();
                System.out.println("異常 JsonMappingException:"+e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("異常 IOException:"+e.getMessage());
            }
            System.out.println("從 Redis 服務中獲取資料");
        }
        return areaList;
    }
}

然後,在 controller 層呼叫這個介面。

第一次執行時,是直接從資料庫中獲取資料。

第二次執行時,是直接從 redis 中獲取資料。

這時,我們也可以通過 redis 視覺化工具,查詢到已經存放到 redis 上的 {key:value}