Redis的使用
一、Redis下載
redis的使用很簡(jiǎn)單,首先需要下載redis陨闹,在本機(jī)上或者是在遠(yuǎn)程服務(wù)器上下載均可楞捂,推薦使用docker的方式下載redis鏡像。
二趋厉、spring boot環(huán)境配置
首先創(chuàng)建一個(gè)web項(xiàng)目寨闹,方便測(cè)試
maven配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
application.properties配置
//Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)
spring.redis.database=0
//Redis服務(wù)器地址
spring.redis.host=192.168.0.24
//Redis服務(wù)器連接端口
spring.redis.port=6379
//Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
//連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-active=200
//連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-wait=-1
//連接池中的最大空閑連接
spring.redis.pool.max-idle=10
//連接池中的最小空閑連接
spring.redis.pool.min-idle=0
//連接超時(shí)時(shí)間(毫秒)
spring.redis.timeout=1000
我們只需要配置spring.redis.host和spring.redis.port即可使用,由于他們的默認(rèn)值分別是localhost和6379君账,所以如果我們把redis下載到了本地繁堡,則什么都不用配置就可以直接使用redis。
三乡数、RedisTemplate與StringRedisTemplate
StringRedisTemplate使用的是StringRedisSerializer來(lái)序列化String椭蹄。
RedisTemplate使用的是JdkSerializationRedisSerializer來(lái)序列化對(duì)象。
StringRedisTemplate指定的范型是String净赴,因此不能用來(lái)存儲(chǔ)對(duì)象绳矩,當(dāng)存入對(duì)象的時(shí)候會(huì)報(bào)錯(cuò),而RedisTemplate可以存入對(duì)象玖翅,但是它是以二進(jìn)制的方式進(jìn)行存儲(chǔ)的翼馆,如果不經(jīng)過(guò)序列化,存入的數(shù)據(jù)完全沒(méi)有可讀性金度,如果要讓數(shù)據(jù)有可讀性应媚,需要我們自己設(shè)置序列化的方式。
在實(shí)際開(kāi)發(fā)中审姓,大多數(shù)情況都是用StringRedisTemplate來(lái)操作珍特,如果需要存入對(duì)象,先把對(duì)象轉(zhuǎn)成jsonString魔吐,再存入redis中扎筒,使用的時(shí)候再轉(zhuǎn)成需要的對(duì)象。
在有特定的需求酬姆,需要在redis中存入對(duì)象的時(shí)候嗜桌,我們一般不用自帶的RedisTemplate,因?yàn)?br> 默認(rèn)的這個(gè)類挺不好用的辞色,它的范型是<Object, Object>的骨宠,因此每次都要寫類型轉(zhuǎn)換的代碼。所以我們一般自定義一個(gè)RedisTemplate相满,范型是<String, Object>层亿,并設(shè)置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工具類
在開(kāi)發(fā)中建蹄,一般會(huì)自己寫工具類來(lái)封裝RedisTemplate碌更,這里只寫了StringRedisTemplate的工具類裕偿,RedisTemplate的工具類與之類似。
@Component
public class RedisStringUtils {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**-------------------------------基礎(chǔ)----------------------------------------*/
/**
* 指定緩存失效時(shí)間
* @param key
* @param time 時(shí)間(秒)
* @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;
}
}
/**
* 獲取緩存失效時(shí)間
* @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;
}
}
/**
* 緩存放入并設(shè)置過(guò)期時(shí)間
* @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);
}
}
測(cè)試
public class RedisTest {
@Autowired
private RedisStringUtils redisStringUtils;
private User user = new User();
@Before
public void before() {
user.setName("八幡");
user.setAge(24);
}
/**
* 測(cè)試普通字符串
*/
@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);
//如果不是數(shù)字incr會(huì)報(bào)錯(cuò)
//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);
}
/**
* 測(cè)試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());
}
/**
* 測(cè)試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);
}
}