目錄
一、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}