SpringBoot整合Redis
Spring Boot Data Redis中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplateの两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。
RedisTemplate(object,object):自动序列化 自动反序列化
StringRedisTemplate(String,String)。
注意:RedisTemplate使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口。
一、环境准备
redis服务器记得把redis.conf中bind属性的值改为 0.0.0.0 ,外部才能使用IP进行连接。
1. 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 配置application.yaml
spring:
redis:
host: 192.168.73.128
port: 7000
database: 0
3. 使用StringRedisTemplate
//测试类启动SpringbootRedisApplication应用
@SpringBootTest(classes = SpringbootRedisApplication.class)
class SpringbootRedisApplicationTests {
//注入StringRedisTemplate
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void contextLoads() {
}
//操作redis中字符串 opsForValue实际操作的是redis中String类型
@Test
void testString() {
//设置key/value对
stringRedisTemplate.opsForValue().set("name","张三");
stringRedisTemplate.opsForValue().set("names","张三2");
//根据key获取value
String name = stringRedisTemplate.opsForValue().get("name");
}
@Test
public void testKey(){
//获取所有的key
Set<String> keys = stringRedisTemplate.keys("*");
keys.forEach(key-> System.out.println(key));
//给key改名
stringRedisTemplate.rename("name","names");
//设置key的超时时间
System.out.println(stringRedisTemplate.expire("names", 15, TimeUnit.SECONDS));
//随机获取key
System.out.println(stringRedisTemplate.randomKey());
//获取key的超时时间
System.out.println(stringRedisTemplate.getExpire("names"));
//返回key的类型
System.out.println(stringRedisTemplate.type("names"));
//删除key
//stringRedisTemplate.delete("name");
//判断是否有这个key
System.out.println(stringRedisTemplate.hasKey("name"));
}
@Test
public void testList(){
//创建一个列表,放入多个元素
stringRedisTemplate.opsForList().leftPushAll("user","张三","李四","王五","赵六","李四");
//截取指定索引之间的内容
stringRedisTemplate.opsForList().trim("user",0,2);
//获取列表所有元素
List<String> user = stringRedisTemplate.opsForList().range("user", 0, -1);
user.forEach(users-> System.out.println(users));
}
//zset
@Test
public void testSet(){
//创建一个set,并放入多个元素
stringRedisTemplate.opsForSet().add("sets","张三","李四","王五","赵六");
//查看所有元素
Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
sets.forEach(set-> System.out.println(set));
//获取set的元素个数
System.out.println(stringRedisTemplate.opsForSet().size("sets"));
}
@Test
public void testZset(){
//设置一个zset,并放入元素
//stringRedisTemplate.opsForZSet().add("zsets","aa",12);
//获取zset所有元素
Set<ZSetOperations.TypedTuple<String>> zsets = stringRedisTemplate.opsForZSet().rangeWithScores("zsets", 0, -1);
//对zset进行遍历
zsets.forEach(keys-> {
System.out.println(keys.getScore());
System.out.println(keys.getValue());
});
}
//hash类型
@Test
public void testHash(){
//创建一个hash类型并放入元素
stringRedisTemplate.opsForHash().put("maps","name","张三");
HashMap<String, String> map = new HashMap<>();
map.put("age","23");
map.put("sex","男");
map.put("address","北京");
//放入一个map集合
stringRedisTemplate.opsForHash().putAll("maps",map);
//根据key获取value
System.out.println(stringRedisTemplate.opsForHash().get("maps", "name"));
//获取map集合中所有的value
System.out.println(stringRedisTemplate.opsForHash().values("maps"));
System.out.println(stringRedisTemplate.opsForHash().keys("maps"));
//获取多个key的value
System.out.println(stringRedisTemplate.opsForHash().multiGet("maps",Arrays.asList("name","age","address")));
}
}
使用RedisTemplate
-
实体类
public class user implements Serializable { //如果要使用RedisTemplate操作redis,必须序列化 private String name; private String sex; private Integer age; private String address; private Date birthday; // gettersetter略 }
-
测试代码
//启动springboot应用 @SpringBootTest(classes = SpringbootRedisApplication.class) public class testRedisTemplate { @Autowired private RedisTemplate redisTemplate; @Test public void testRedisTemplate(){ user user = new user(); user.setName("张三"); user.setAddress("北京"); user.setBirthday(new Date()); user.setAge(12); user.setSex("男"); redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); redisTemplate.opsForValue(). } }
终端中,无法查看数据,RDM中查看,刚刚插入的内容,全部都是系列化之后的内容
-
RedisTemplate对象中,key和value的序列化方式默认都是jdk的序列化方式,这种方式会将放入redis的内容全部变成序列化后的内容,会导致在redis终端无法进行操作,那么我们可以修改key序列化方案
@Autowired private RedisTemplate redisTemplate; @Test public void testRedisTemplate(){ //修改默认序列化方案 redisTemplate.setKeySerializer(new StringRedisSerializer()); user user = new user(); user.setName("张三"); user.setAddress("北京"); user.setBirthday(new Date()); user.setAge(12); user.setSex("男"); redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); }
再此去RDM中查看,发现只有内容序列化了,key是没有序列化的,我们也可以在终端中通过key进行操作了。
- 其它几种数据类型的使用
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate() throws InterruptedException {
redisTemplate.setKeySerializer(new StringRedisSerializer());
//修改hashKey的序列化方案
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
user user = new user();
user.setName("张三");
user.setAddress("北京");
user.setBirthday(new Date());
user.setAge(12);
user.setSex("男");
//创建list类型
redisTemplate.opsForList().leftPush("userList",user);
//创建set类型
redisTemplate.opsForSet().add("userSet",user);
//创建zset类型
redisTemplate.opsForZSet().add("userZset",user,10);
//创建hash类型
redisTemplate.opsForHash().put("userMap","name",user);
userList",user);
//创建set类型
redisTemplate.opsForSet().add("userSet",user);
//创建zset类型
redisTemplate.opsForZSet().add("userZset",user,10);
//创建hash类型
redisTemplate.opsForHash().put("userMap","name",user);
Bound API
Spring Data为了方便我们对redis进行更友好的操作 因此又提供了bound api简化操作
@SpringBootTest(classes = SpringbootRedisApplication.class)
public class testBoundAPI {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testBound(){
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate stringRedisTemplate 将一个key多次操作进行绑定 对key绑定
stringRedisTemplate.opsForValue().set("name","张三");
stringRedisTemplate.opsForValue().append("name","是一个顽固分子");
System.out.println(stringRedisTemplate.opsForValue().get("name"));
//对字符串类型进行key绑定 后续所有操作都是基于这个key的操作,直接操作name对象了
BoundValueOperations<String, String> name = stringRedisTemplate.boundValueOps("name");
name.append("张三不是");
//获取key的长度
System.out.println(name.size());
//获取所有key的value
System.out.println(name.get());
}
}
set、zset、hash、list也分别可以使用:
stringRedisTemplate.boundSetOps("set");
stringRedisTemplate.boundZSetOps("zSet");
stringRedisTemplate.boundHashOps("hash");
stringRedisTemplate.boundListOps("list");
通过返回的key对象,我们可以使用更方便的api对redis进行操作。
总结:
- 针对于日后处理key value 都是string类型使用 ztringRedisTemplate
- 针对于日后处理key value 存在对象 使用 RedisTemplate(必须先序列化)
- 针对于同一个key需要进行多次操作,可以使用boundxxxOps绑定对应的数据类型的key,使用更简便的api操作redis
应用场景:
- 利用redis中字符串类型完成 项目中手机验证码存储的实现。
- 利用redis中字符串完成 具有失效性业务功能 12306 淘宝 订单一段时间后自动失效。
- 利用redis完成分布式集群系统中Session共享
- 利用redis zset类型 可排序set类型 元素 分数 排行榜之类功能 商品销售排行榜(商品id,商品销量)。
- 利用redis存储认证之后token信息。超时失效。
- 利用redis解决分布式集群系统中分布式锁问题。