Redis 入門與應用
目錄
一、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}