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