首先先介绍下如何在linux上安装redis(前提,你的windows和你的linux的ip地址可以互相ping通)
1、下载redis安装包 网址 https://redis.io/
Redis的版本规则如下: 次版本号(第一个小数点后的数字)为偶数的版本是稳定版本(2.4、2.6等),奇数为非稳定版本(2.5、2.7),一般推荐在生产环境使用稳定版本。 但是, 在Windows平台下: 64位系统的最新稳定版本是2.8.9 32位系统的最新稳定版本是2.6 说明:Redis官方是不支持Windows平台的,Windows版本是由微软自己建立的分支,基于官方的Redis源码上进行编译、发布、维护的,所以Windows平台的Redis版本都要略低于官方版本。
2、把redis安装包传到linux上
3、介绍下redis可执行文件
4、下面安装redis
1、mkdir -p /usr/local/src/redis
2、把传到linux中的安装包移到/usr/local/src/redis目录下
3、cd /usr/local/src/redis
4、tar xzf redis-4.0.2.tar.gz
5、cd redis-4.0.2
6、make
7、make install
8、接下来修改配置文件,让redis在后台执行 cp redis.conf /etc/
9、vi /etc/redis.conf
10、在配置文件加上 daemonize yes
11、 起动redis redis-server /etc/redis.conf
12、证明redis开启的方法,用redis客户端,IP地址和端口号根据配置文件中的设置 redis-cli -h 127.0.0.1–p 6379
13、在redis-cli中输入 PING 如果返回PONG 则配置成功
接下来介绍SpringBoot和redis的整合
1、导入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0";; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";;
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd";>;
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.springboot</groupId>
<artifactId>springboot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<!--mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 由于这里使用了springboot 可以根据实际情况添加 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
目录结构如下:
标准的SSM层不再介绍,想了解的同学可以看我之前的博客,网上大多数springboot教程主要是spring-data-redis方式 ,但是有的人爱用jedis,我主要介绍jedis与SpringBoot整合有关的部分
我们要创建一个RedisConfig,替代xml文件中有关jedis的配置,我们首先先看jedis在xml中怎么配置
<?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:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 连接池信息 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 根据实际情况进行配置其他参数-->
<property name="maxTotal" value="${maxTotal}"/>
</bean>
<!-- 分片式集群,可配置多个list连接多个redis服务器-->
<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="jedisPoolConfig"/>
<constructor-arg index="1">
<list>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${hostip1}"/>
<constructor-arg index="1" value="${port1}"/>
</bean>
</list>
</constructor-arg>
</bean>
</beans>
上面的代码先创建了一个JedisPoolConfig对象,然后新建一个ShardedJedisPool对象,构造器形式,把JedisPoolConfig放进构造器,再创建一个JedisSharedInfo对象,放在list中,然后把list放进构造器,下面看springboot如何做,在yml文件中写上配置
redis:
maxTotal: 50
hostip: 172.22.22.240
port: 6379
然后创建一个RedisConfig 大家可以对照xml文件中的配置和我上面的介绍,是不是发现和springboot 简化了xml的配置,但是实现是一样的,我们可以举一反三,把以前的xml形式的项目转到springboot形式的代码。
package com.springboot.config;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;
@Configuration
public class RedisConfig {
private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("${redis.maxTotal}")
private Integer maxTotal;
@Value("${redis.hostip}")
private String hostip;
@Value("${redis.port}")
private Integer port;
@Bean
public ShardedJedisPool shardedJedisPool() {
//配置连接池
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
ArrayList<JedisShardInfo> arrayList = new ArrayList<>();
arrayList.add(new JedisShardInfo(hostip, port));
return new ShardedJedisPool(jedisPoolConfig, arrayList);
}
}
接下来新建RedisUtils接口
package com.springboot.service.util;
/**
* @author shanchenyang
* @time 创建时间:2017年10月13日 下午7:22:48
*
*/
public interface RedisUtils {
//保存
public String set(String key,String value);
//根据key查询
public String get(String key);
//删除del
public Long del(String key);
//设置key生存时间
public Long expire(String key, Integer time);
//设置一个值并设置生存时间
public Long set(String key,String value,Integer time);
//值加1
public Long incr(String key);
//是否有key
public Boolean hasKey(String key);
}
package com.springboot.service.util;
/**
* @author shanchenyang
* @time 创建时间:2017年10月13日 下午7:25:00
*
*/
public interface Function<E, T> {
public T callback(E e);
}
RedisUtilsImp实现,这里用了一个技巧,因为jedis每个实现都需要开始和释放连接,所以把开始和释放连接抽取出来,简化代码。类似于js的callback的形式。
package com.springboot.service.imp.util;
import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.springboot.service.util.Function;
import com.springboot.service.util.RedisUtils;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
/**
* @author shanchenyang
* @time 创建时间:2017年10月13日 下午7:26:00
*
*/
@Component
public class RedisUtilsImpl implements RedisUtils {
private static final Logger logger = getLogger(RedisUtilsImpl.class);
//用到的时候再注入required=false
@Autowired (required=false)
private ShardedJedisPool shardedJedisPool;
public <T> T excute(Function<ShardedJedis, T> fun){
ShardedJedis shardedJedis = null;
try {
// 从连接池中获取到jedis分片对象
shardedJedis = shardedJedisPool.getResource();
return fun.callback(shardedJedis);
} catch (Exception e) {
logger.error("redis error");
} finally {
if (null != shardedJedis) {
// 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态
shardedJedis.close();
}
}
return null;
}
public String set(final String key,final String value) {
return excute(new Function<ShardedJedis, String>() {
public String callback(ShardedJedis e) {
return e.set( key, value);
}
});
}
public String get(final String key) {
return excute(new Function<ShardedJedis, String>() {
public String callback(ShardedJedis e) {
return e.get(key);
}
});
}
public Long del(final String key) {
return excute(new Function<ShardedJedis, Long>() {
public Long callback(ShardedJedis e) {
return e.del(key);
}
});
}
public Long expire(final String key,final Integer seconds) {
return excute(new Function<ShardedJedis, Long>() {
public Long callback(ShardedJedis e) {
return e.expire(key, seconds);
}
});
}
public Long set(final String key,final String value,final Integer seconds) {
return excute(new Function<ShardedJedis, Long>() {
public Long callback(ShardedJedis e) {
e.set(key, value);
return e.expire(key, seconds);
}
});
}
public Long incr(final String key) {
return excute(new Function<ShardedJedis, Long>() {
public Long callback(ShardedJedis e) {
return e.incr(key);
}
});
}
public Boolean hasKey(final String key) {
return excute(new Function<ShardedJedis, Boolean>() {
public Boolean callback(ShardedJedis e) {
return e.exists(key);
}
});
}
}
接着就是运用redis实现缓存,如果缓存中有数据,直接从redis中拿,如果缓存中没有,从数据库中查出来并且把数据放到redis中
package com.springboot.service.imp;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.springboot.entity.Student;
import com.springboot.mapper.StudentMapper;
import com.springboot.service.StudentService;
import com.springboot.service.util.RedisUtils;
/**
* @author shanchenyang
* @time 创建时间:2017年10月11日 下午8:41:27
*
*/
@Service
public class StudentServiceImp implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Autowired
private RedisUtils redisUtils;
private static final Logger logger = getLogger(StudentServiceImp.class);
private static final ObjectMapper MAPPER = new ObjectMapper();
public static final String REDIS_KEY = "REDIS_KEY";
public List<Student> getAllStudents() {
Boolean hasKey = redisUtils.hasKey(REDIS_KEY);
if (hasKey) {
String redisList = redisUtils.get(REDIS_KEY);
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, Student.class);
try {
return MAPPER.readValue(redisList, javaType);
} catch (Exception e) {
logger.error("json error");
}
return new ArrayList<Student>();
} else {
List<Student> selectAll = studentMapper.selectAll();
String writeValueAsString = "";
try {
writeValueAsString = MAPPER.writeValueAsString(selectAll);
} catch (JsonProcessingException e) {
logger.error("json error");
}
redisUtils.set(REDIS_KEY, writeValueAsString);
return selectAll;
}
}
}
首先打开druid 如图一样什么都没有。
controller层代码如下
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/getData" )
public List<Student> getStudents() {
return studentService.getAllStudents();
}
}
访问一下看看
第一次访问redis中还没有数据,所以是从数据库中查找,看druid已经有数据了,在多刷新几次 localhost:8080/getData druid也不变,因为是从数据库中拿的
redis中的值如下
把这个key删掉然后访问 localhost:8080/getData 再看druid,好了redis实现了!!
github 地址 https://github.com/CharlsShan/springboot-demo