Redis环境搭建
环境
- MacOS (本篇博客介绍)
- Windows (坑比较少,网上教程也比较多,比如这篇)
Redis配置步骤
有两种方案可以配置Redis,【1】官网下载安装包方式【2】通过homebrew安装方式
安装包方式
下载安装包
去Redis官网下载Stable 稳定版
安装
这里通过命令行安装,在解压后的目录下
redis-6.2.2
:
编译测试:
sudo make test
编译安装:
sudo make install
安装完后可以看见目录如下:
Redis配置
注意这里坑比较多!!!先找到
redis.conf
文件,这是redis的配置文件,我们一般需要配置的是服务器的登陆密码。可以打开文件后搜索requirepass
修改后面的的密码即可,注意还要去掉前面的#
。
还可以继续配置aof或者rdb的持久方式:
开启RDB
将包含save的那几行的
#
去掉即可开启AOF
将apeendonly的值改为yes即可
启动Redis服务
这里是个大坑!!!注意到上一步我们设置了conf文件,如果想要配置生效,启动的时候需要加上conf文件。直接打开终端,将conf和
redis-server
文件拖入,后者先cd进入上面的redis解压目录。
然后回车即可看见服务正常启动,看到下面的界面就可以了。
这里如果觉得每次麻烦,可以封装成一个执行文件:
vim redis
新建名为redis的文件,写入
/.../redis-6.2.2/src/redis-server /.../redis-6.2.2/redis.conf
给文件添加执行全县
chmod +x redis
启动服务
./redis
注意
上述带有conf文件的启动方式,即使你通过
control+c
关掉服务后,redis服务会依然在后台启动,若是修改配置后重启,可以在mac的活动监视器
搜索redis
关掉服务,再通过步骤4启动服务。
homebrew方式
Springboot整合Redis
配置好Redis是开发的第一步,如何使用才是关键,这里列出我平时通过Springboot使用Redis时的部分代码。我一般都是把Redis放在service层,供其他业务service调用。
pom依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Redis的yaml配置
spring:
#redis
redis:
host: localhost
password: 123456
port: 6379
pool:
max-idle: 100
min-idle: 1
max-active: 1000
max-wait: -1
- RedisService
列出的是Redis五种数据类型的crud,方法的传入参数可以根据自己的业务逻辑相应修改。
package com.qian.service;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisService {
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
/*
* 字符串类型操作
*/
/**
* redisTemplate操作普通字符串(存值)
*
* @param key
* @param value
*/
public void redisSetString(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* redisTemplate操作普通字符串 (取值)
*
* @param key
*/
public Object redisGetString(String key) {
return redisTemplate.opsForValue().get(key);
}
/*
* 列表类型操作
*/
/**
* 将一个list集合存放到redis当中
*
* @param key
*/
public void redisSetList(String key, List<Object> list) {
// List<Integer> list = Arrays.asList(9, 2, 3, 4);
for (Object obj : list) {
// 从当前的数据 向右添加
redisTemplate.opsForList().rightPush(key, obj);
// 从当前的数据 向左添加
// redisTemplate.opsForList().leftPush(key, obj);
}
}
/**
* 获取list(获取所有的数据)
*
* @param key
* @return
*/
public Object getList(String key) {
return redisTemplate.opsForList().range(key, 0, getListSize(key));
}
/**
* 获取list指定key的长度
*
* @param key
* @return
*/
public Long getListSize(String key) {
return redisTemplate.opsForList().size(key);
}
/*
* 哈希类型操作
*/
/**
* 将map存放到reids
*
* @param key
*/
public void setHash(String key) {
Map<String, String> hashMap = new HashMap();
//使用RedisTemplate 有些情况会乱码
hashMap.put("redis", "redis");
hashMap.put("mysql", "mysql");
for (Entry<String, String> keyValue : hashMap.entrySet()) {
redisTemplate.opsForHash().put(key, keyValue.getKey(), keyValue.getValue());
}
}
/**
* 获取指定key1的值
*
* @param key
* @param key1
* @return
*/
public Object getHash(String key, String key1) {
// 检测 是否 存在该键
boolean isKey = redisTemplate.opsForHash().hasKey(key, key1);
return redisTemplate.opsForHash().get(key, key1);
}
/**
* 获取指定key的所有值
*
* @param key
*
* @return
*/
public Object getHash(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 根据具体key移除具体的值
*
* @param key
*
* @return
*/
public void removeKey(String key, String key1) {
redisTemplate.opsForHash().delete(key, key1);
}
/**
* 移除key值 则key里面的所有值都被移除
*
* @param key
*
* @return
*/
public void removeStringKey(String key) {
redisTemplate.delete(key);
}
/*
* 集合类型操作
*/
/**
* set存入redis中
*
* @param key
*/
public void setSet(String key) {
Set<Object> set = new HashSet();
set.add("setKey");
set.add("tesetKey");
for (Object object : set) {
redisTemplate.opsForSet().add(key, object);
}
}
/**
* 从redis中取出set
*
* @param key
* @return
*/
public Object getSet(String key) {
return redisTemplate.opsForSet().members(key);
}
/*
* 有序集合类型操作
*/
/**
* sortset存入redis中
*
* @param key
*/
public void setZSet(String key) {
Set<Object> set = new HashSet();
set.add("setKey");
set.add("tesetKey");
int i = 0;
for (Object object : set) {
i++;
redisTemplate.opsForZSet().add(key, object, i);
}
}
/**
* 从redis中取出sortset
*
* @param key
* @return
*/
public Object getZSet(String key) {
Long size = redisTemplate.opsForZSet().size(key);
return redisTemplate.opsForZSet().rangeByScore(key, 0, size);
}
/*
* RedisTemplate操作5种基本类型数据,有一些共同的API
*/
/**
*
* 指定缓存失效时间
*
* @param key
* 键
*
* @param time
* 时间(秒)
*
* @return
*
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
*
* 判断key是否存在
*
* @param key
* 键
*
* @return true 存在 false不存在
*
*/
public boolean checkKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
关于可视化工具的key/value乱码问题
我使用redis官方提供的Redisinsight,发现插入key后有乱码的问题。可以使用配置类设置序列化
@Configuration
public class RedisConfig {
@Autowired
private RedisTemplate redisTemplate;
@Bean
public RedisTemplate redisTemplateInit() {
//设置序列化Key的实例化对象
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置序列化Value的实例化对象
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
如果是使用的Fastjson对对象进行序列化,也可以自定义序列化类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.util.Assert;
import java.nio.charset.Charset;
/**
* Redis使用FastJson序列化
*
* @author sg
*/
public class FastJsonRedisSerializer<T> implements RedisSerializer<T>
{
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static
{
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
public FastJsonRedisSerializer(Class<T> clazz)
{
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
protected JavaType getJavaType(Class<?> clazz)
{
return TypeFactory.defaultInstance().constructType(clazz);
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}