公司的项目中用到了Redis,最近一直在学习这一块。从开始学习到现在,总体给我的感觉是Redis上手比较容易,但是精通需要大量的实践和研究的。好在我们公司对Redis的使用并不是那么深入,目前只进行些简单的操作。总结这几天的学习结果,记录下来,希望有助于巩固和提高。
说明:我的Redis服务是搭建在虚拟机Linux(Read Heat6.2)系统上的,Mysql数据库安装在本机,虚拟机的网络连接模式为桥接,和本机公用一个网段。网上有很多搭建的例子,这里就不进行说明了。
导包:
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
首先是SpringBoot中的配置文件(application.yml类型的配置文件,该类型文件对书写格式有严格的要求)
server:
port: 8090
spring:
datasource:
url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
username: xxx
password: xxx
driver-class-name: com.mysql.jdbc.Driver
test-on-borrow: false
test-while-idel: true
time-between-eviction-runs-millis: 3600000
tomcat:
max-wait: 10000
max-active: 50
http:
encoding:
force: true
jpa:
hibernate:
ddl-auto: update
max_fetch_depth: 2
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
max_fetch_depth: 2
format_sql: true
show-sql: true
redis:
host: xxx
password:
port: 6379
pool:
# 连接池中的最大空闲连接
max-idle: 8
min-idle: 0
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 1
# 连接超时时间(毫秒)
timeout: 60000
接下来是对Redis数据操作类的配置,提供了数据的序列化方式。Spring封装了RedisTimplement对象来对Redis进行操作,该模板默认采用JdkSerializationRedisSerializer的二进制序列化方式。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
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.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration //标注一个配置类,交由spring管理
public class Config extends CachingConfigurerSupport{
@Autowired
private RedisConnectionFactory factory; //通过RedisConnectionFactory 引入redis在配置文件中的连接配置
/* * 此处为什么要序列化 原因:普通的连接使用没有办法把Java对象直接存入Redis,
* 而需要我们自己提供方案-对象序列化,然后存入redis,
* 取回序列化内容后,转换为java对
* */
// 实例化 RedisTemplate 对象
@Bean
public RedisTemplate<String,Object> redisTemplate(){
RedisTemplate<String,Object> template = new RedisTemplate<>();
initDomainRedisTemplate(template, factory); // 设置数据存入 redis 的序列化方式
return template;
}
public void initDomainRedisTemplate(RedisTemplate template,RedisConnectionFactory factory){
template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的 value 值
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper(); //ObjectMapper是jackson的主要类,作用序列化
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //设置任何字段可见
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//反序列化
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);//设置序列化反序列化redis的value值
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setKeySerializer(stringRedisSerializer);//设置序列化反序列化key值的方式为String
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
redisTemplate.afterPropertiesSet(); //初始化操作,在设置完成后进行
}
//实例化HashOperations对象,可以使用Hash类型操作
@Bean
public HashOperations<String,String,Object> hashOperations(RedisTemplate<String,Object> redisTemplate){
return redisTemplate.opsForHash(); //opsForHash()该方法用于操作Hash
}
//实例化ListOperations对象,可以使用List类型操作
@Bean
public ListOperations<String,Object> listOperations(RedisTemplate<String,Object> redisTemplate){
return redisTemplate.opsForList(); //opsForList()该方法用于操作List
}
}
然后就是对Redis数据进行操作的工具类了,在此列举了三种数据类型,String、Hash、List
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Autowired
private HashOperations<String,String,Object> hashOperations;
@Autowired
private ListOperations<String,Object> listOperations;
/*---------------------------------------------公共区域---------------------------------------------------*/
//判断key是否存在
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
//根据key删除key和value
public void deleteByKey(String key){
redisTemplate.delete(key);
}
/*
* 设置key的有效期
* @param key,time(有效时间),unit(hours,days,minutes)
* */
public void setExpire(String key,long time,TimeUnit unit){
if (time != -1){
redisTemplate.expire(key,time,unit);
}
}
/*---------------------------------------------公共区域---------------------------------------------------*/
/*----------------------------------------------String-------------------------------------------------*/
//根据key获取value值
public String getValue(String key){
return (String) redisTemplate.opsForValue().get(key);
}
//插入数据
public void setValue(String key,String value){
redisTemplate.opsForValue().set(key,value);
}
/*----------------------------------------------String------------------------------------------------*/
/*-----------------------------------------------hash--------------------------------------------------*/
//存入hash类型的值
public void addAllForHash(String key, Map<String,Object> map){
hashOperations.putAll(key,map);
}
/*
* 根据key查询该key对应map下的所有value
* @param key
* @return List<AllValue>
* */
public List<Object> getAllValueForHash(String key){
return hashOperations.values(key);
}
//获取Hash中的单个value
public Object getValueForHash(String key, String hashKey){
return hashOperations.get(key,hashKey);
}
//获取Hash数量
public Long getCount(String key){
return hashOperations.size(key);
}
/*
* 根据key和hashKey删除value
* @param key,hashKey
* @return void
* */
public void deleteValueByKeyAndHashKey(String key,String hashKey){
hashOperations.delete(key,hashKey);
}
/*
* 判断当前key中hashKey是否存在
* @param key,hashKey
* @return true / false
* */
public boolean hasHashKey(String key,String hashKey){
return hashOperations.hasKey(key,hashKey);
}
/*
* 查询key下所有Hash值
* @param key
* @return Map<key,value>
* */
public Object getAllHashByKey(String key){
return hashOperations.entries(key);
}
/*-----------------------------------------------hash----------------------------------------------------*/
/*-----------------------------------------------list----------------------------------------------------*/
/*
* 从list队列尾部存数据
* @param key,List
* @return null
* */
public void rightPushAll(String key, List<String> values){
listOperations.rightPushAll(key,values);
}
/*
* 从list队列尾部存数据
* @param key,value
* @return null
* */
public void rightPush(String key, String value){
listOperations.rightPush(key,value);
}
/*
*从list队列中取出全部数据(0,listSize)
* @param key
* @return List
* */
public List<Object> getListAll(String key){
return listOperations.range(key,0,listOperations.size(key));
}
/*-----------------------------------------------list---------------------------------------------------*/
}