Redis的使用
一、Redis下载
redis的使用很简单,首先需要下载redis,在本机上或者是在远程服务器上下载均可,推荐使用docker的方式下载redis镜像。
二、spring boot环境配置
首先创建一个web项目,方便测试
maven配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
application.properties配置
//Redis数据库索引(默认为0)
spring.redis.database=0
//Redis服务器地址
spring.redis.host=192.168.0.24
//Redis服务器连接端口
spring.redis.port=6379
//Redis服务器连接密码(默认为空)
spring.redis.password=
//连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=200
//连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
//连接池中的最大空闲连接
spring.redis.pool.max-idle=10
//连接池中的最小空闲连接
spring.redis.pool.min-idle=0
//连接超时时间(毫秒)
spring.redis.timeout=1000
我们只需要配置spring.redis.host和spring.redis.port即可使用,由于他们的默认值分别是localhost和6379,所以如果我们把redis下载到了本地,则什么都不用配置就可以直接使用redis。
三、RedisTemplate与StringRedisTemplate
StringRedisTemplate使用的是StringRedisSerializer来序列化String。
RedisTemplate使用的是JdkSerializationRedisSerializer来序列化对象。
StringRedisTemplate指定的范型是String,因此不能用来存储对象,当存入对象的时候会报错,而RedisTemplate可以存入对象,但是它是以二进制的方式进行存储的,如果不经过序列化,存入的数据完全没有可读性,如果要让数据有可读性,需要我们自己设置序列化的方式。
在实际开发中,大多数情况都是用StringRedisTemplate来操作,如果需要存入对象,先把对象转成jsonString,再存入redis中,使用的时候再转成需要的对象。
在有特定的需求,需要在redis中存入对象的时候,我们一般不用自带的RedisTemplate,因为
默认的这个类挺不好用的,它的范型是<Object, Object>的,因此每次都要写类型转换的代码。所以我们一般自定义一个RedisTemplate,范型是<String, Object>,并设置key和value的序列化方式,综合情况下考虑,key一般使用String的序列化方式,value一般使用jackson的序列化方式。
/**
* create by bafan 2019/04/24
* redis配置类
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
Redis工具类
在开发中,一般会自己写工具类来封装RedisTemplate,这里只写了StringRedisTemplate的工具类,RedisTemplate的工具类与之类似。
@Component
public class RedisStringUtils {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**-------------------------------基础----------------------------------------*/
/**
* 指定缓存失效时间
* @param key
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if(time > 0) {
return stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取缓存失效时间
* @param key
* @return
*/
public long getExpire(String key) {
return stringRedisTemplate.getExpire(key);
}
/**
* 判断key是否存在
* @param key
* @return
*/
public boolean hasKey(String key) {
try {
return stringRedisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key
*/
public void del(String... key) {
if(key != null && key.length > 0) {
if(key.length == 1) {
stringRedisTemplate.delete(key[0]);
} else {
stringRedisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/**-------------------------------String----------------------------------------*/
/**
* 获取value
* @param key
* @return
*/
public Object get(String key) {
return key == null ? null : stringRedisTemplate.opsForValue().get(key);
}
/**
* 缓存放入
* @param key
* @param value
* @return
*/
public boolean set(String key, String value) {
try {
stringRedisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 缓存放入并设置过期时间
* @param key
* @param value
* @param time
* @return
*/
public boolean set(String key, String value, long time) {
try {
stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key
* @param delta
* @return
*/
public long incr(String key, long delta) {
if(delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return stringRedisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key
* @param delta
* @return
*/
public long decr(String key, long delta) {
if(delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return stringRedisTemplate.opsForValue().increment(key, -delta);
}
}
测试
public class RedisTest {
@Autowired
private RedisStringUtils redisStringUtils;
private User user = new User();
@Before
public void before() {
user.setName("八幡");
user.setAge(24);
}
/**
* 测试普通字符串
*/
@Test
public void test1() {
redisStringUtils.set("bafan1", "1");
redisStringUtils.set("bafan2", "hello", 60);
String bafan1 = (String)redisStringUtils.get("bafan1");
String bafan2 = (String)redisStringUtils.get("bafan2");
System.out.println(bafan1 + "..." + bafan2);
boolean b1 = redisStringUtils.hasKey("bafan1");
boolean b2 = redisStringUtils.hasKey("bafan3");
System.out.println(b1 + "..." + b2);
long expire1 = redisStringUtils.getExpire("bafan1");
long expire2 = redisStringUtils.getExpire("bafan2");
System.out.println(expire1 + "..." + expire2);
redisStringUtils.incr("bafan1", 3l);
//如果不是数字incr会报错
//redisStringUtils.incr("bafan2", 3l);
String bafan3 = (String)redisStringUtils.get("bafan1");
String bafan4 = (String)redisStringUtils.get("bafan2");
System.out.println(bafan3 + "..." + bafan4);
redisStringUtils.decr("bafan1", 2l);
String bafan5 = (String)redisStringUtils.get("bafan1");
String bafan6 = (String)redisStringUtils.get("bafan2");
System.out.println(bafan5 + "..." + bafan6);
redisStringUtils.expire("bafan1", 100);
long expire3 = redisStringUtils.getExpire("bafan1");
System.out.println(expire3);
}
/**
* 测试DTO类
*/
@Test
public void test2() {
redisStringUtils.set("bafan3", JSON.toJSONString(user));
Object o = redisStringUtils.get("bafan3");
User user = JSON.parseObject(o.toString(), User.class);
System.out.println(user.getName() + "..." + user.getAge());
}
/**
* 测试Map
*/
@Test
public void test3() {
Map<String, String> map = new HashMap<>();
map.put("bafan1", "1");
map.put("bafan2", "2");
redisStringUtils.set("bafan4", JSON.toJSONString(map));
Object o = redisStringUtils.get("bafan4");
Map<String, String> map1 = JSON.parseObject(o.toString(), Map.class);
System.out.println(map1);
}
}