springboot集成redis步骤
1.创建springboot项目
2.配置连接
3.测试
创建springboot项目
创建以一个Maven项目
创建之后查看pom.xml配置文件,可以看到
pom文件里面导入了 data-redis 的依赖,那我们就可以在知道,springboot集成redis操作redis数据库是通过这个依赖完成的,点进这个依赖,他的底层
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置连接
#配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
配置依赖在application.properties文件里面配置
需要配置的东西在 RedisProperties.class,之里面现在是默认的本地配置如果有需要修改其他主机的配置那就可以在配置文件里进行修改
在application.properties里还可以配置连接池,之前使用的是jedis,现在建议使用的是lettuce,因为在RedisAutoConfiguration类中的redisTemplate方法中引入一个了一个接口RedisConnectionFactory的参数,如果可以看到源码的话点进去可以看到RedisConnectionFactory的实现类,它的实现类有两种一个是JedisConnectionFactory实现类这里很多的方法是不生效的,那就是说不可以用,但是在LettuceConnectionFactory实现类里是生效的所以这里推荐使用连接池lettuce
测试
1.在测试类导入RedisTemplate数据库驱动能通过redisTemplate对象调用方法来操作redis
@Autowired
private RedisTemplate redisTemplate;
使用细节
序列化问题
Redis 对象都需要序列化(否则会报错)
默认的 RedisTemplate<Object, Object> 两个泛型都是object类型后面使用需要强制转换,我们平时常使用的是 RedisTemplate<String, Object>所以后面我们可以去替换这个默认的RedisTemplate。
由于我们在Redis 中尝试用的是String类型所以Redis单独提出来了一个bean
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.data.redis;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Christian Dupuis
* @author Christoph Strobl
* @author Phillip Webb
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Marco Aust
* @author Mark Paluch
* @since 1.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
自定义RedisTemplate<String, Object>
package com.kunag.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
// Redis序列化固定模板
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
/**
* 数据库驱动
* 原本的 RedisTemplate<Object, Object> 修改为 RedisTemplate<String, Object>
*/
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 创建连接,连接工程
template.setConnectionFactory(factory);
/**
* 序列化配置
* 不同的序列化方式对应了不同的序列化对象
*/
// Json序列化对象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer
= new Jackson2JsonRedisSerializer(Object.class);
// 通过ObjectMapper转义
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用iackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
自定义封装工具类RedisUtil
package com.kunag.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 设置有效时间
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
Boolean ret = redisTemplate.expire(key, timeout, unit);
return ret != null && ret;
}
/**
* 删除单个key
* @param key 键
* @return true=删除成功;false=删除失败
*/
public boolean del(final String key) {
Boolean ret = redisTemplate.delete(key);
return ret != null && ret;
}
/**
* 删除多个key
* @param keys 键集合
* @return 成功删除的个数
*/
public long del(final Collection<String> keys) {
Long ret = redisTemplate.delete(keys);
return ret == null ? 0 : ret;
}
/**
* 存入普通对象
* @param key Redis键
* @param value 值
*/
public void set(final String key, final Object value) {
redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES);
}
/*******************存储普通对象操作*********************/
/**
* 存入普通对象
* @param key 键
* @param value 值
* @param timeout 有效期,单位秒
*/
public void set(final String key, final Object value, final long timeout) {
redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
/**
* 获取普通对象
* @param key 键
* @return 对象
*/
public Object get(final String key) {
return redisTemplate.opsForValue().get(key);
}
/*******************存储Hash操作*********************/
/**
* 往Hash中存入数据
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public void hPut(final String key, final String hKey, final Object value) {
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 往Hash中存入多个数据
* @param key Redis键
* @param values Hash键值对
*/
public void hPutAll(final String key, final Map<String, Object> values) {
redisTemplate.opsForHash().putAll(key, values);
}
/**
* 获取Hash中的数据
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public Object hGet(final String key, final String hKey) {
return redisTemplate.opsForHash().get(key, hKey);
}
/**
* 获取多个Hash中的数据
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public List<Object> hMultiGet(final String key, final Collection<Object> hKeys) {
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/*******************存储Set相关操作*********************/
/**
* 往Set中存入数据
* @param key Redis键
* @param values 值
* @return 存入的个数
*/
public long sSet(final String key, final Object... values) {
Long count = redisTemplate.opsForSet().add(key, values);
return count == null ? 0 : count;
}
/**
* 删除Set中的数据
* @param key Redis键
* @param values 值
* @return 移除的个数
*/
public long sDel(final String key, final Object... values) {
Long count = redisTemplate.opsForSet().remove(key, values);
return count == null ? 0 : count;
}
/*******************存储List相关操作*********************/
/**
* 往List中存入数据
* @param key Redis键
* @param value 数据
* @return 存入的个数
*/
public long lPush(final String key, final Object value) {
Long count = redisTemplate.opsForList().rightPush(key, value);
return count == null ? 0 : count;
}
/**
* 往List中存入多个数据
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public long lPushAll(final String key, final Collection<Object> values) {
Long count = redisTemplate.opsForList().rightPushAll(key, values);
return count == null ? 0 : count;
}
/**
* 往List中存入多个数据
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public long lPushAll(final String key, final Object... values) {
Long count = redisTemplate.opsForList().rightPushAll(key, values);
return count == null ? 0 : count;
}
/**
* 从List中获取begin到end之间的元素
* @param key Redis键
* @param start 开始位置
* @param end 结束位置(start=0,end=-1表示获取全部元素)
* @return List对象
*/
public List<Object> lGet(final String key, final int start, final int end) {
return redisTemplate.opsForList().range(key, start, end);
}
}