数据类型:String、列表List、集合Set、有序集合SortedSet及哈希Hash存储
1.String
字符串很常见,不用多说,当然我们也可以吧一个对象通过ObjectMapper等JSON解析框架进行序列化与反序列化,从而将对象转化为JSON格式的字符串,存起来。
package com.debug.middleware.server;
//导入包
import com.debug.middleware.server.entity.Person;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//单元测试类
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisTest2 {
//定义日志
private static final Logger log= LoggerFactory.getLogger(RedisTest2.
class);
//定义RedisTemplate操作组件
@Autowired
private RedisTemplate redisTemplate;
//JSON序列化与反序列化框架类
@Autowired
private ObjectMapper objectMapper;
//单元测试方法
@Test
public void one() throws Exception{
//构造用户个人实体对象
Person p=new Person(10013,23, "修罗", "debug", "火星");
//定义key与即将存入缓存中的value
final String key="redis:test:1";
String value=objectMapper.writeValueAsString(p);
//写入缓存中
log.info("存入缓存中的用户实体对象信息为:{} ", p);
redisTemplate.opsForValue().set(key, value);
//从缓存中获取用户实体信息
Object res=redisTemplate.opsForValue().get(key);
if (res! =null){
Person resP=objectMapper.readValue(res.toString(), Person.class);
log.info("从缓存中读取信息:{} ", resP);
}
}
}
2. 列表
Redis的列表类型跟Java的List类型很类似,用于存储一系列具有相同类型的数据。其底层对于数据的存储和读取可以理解为一个“数据队列”。
在Spring Boot整合Redis的项目使用List类型存储数据时,可以通过push添加、pop获取等操作存储获取的数据。在实际应用场景中,Redis的列表List类型特别适用于 “排名” “排行榜” “近期访问数据列表” 等业务场景,是一种很实用的存储类型。
//列表类型
@Test
public void two() throws Exception{
//构造已经排好序的用户对象列表
List<Person> list=new ArrayList<>();
list.add(new Person(1,21, "修罗", "debug", "火星"));
list.add(new Person(2,22, "大圣", "jack", "水帘洞"));
list.add(new Person(3,23, "盘古", "Lee", "上古"));
log.info("构造已经排好序的用户对象列表: {} ", list);
//将列表数据存储至Redis的List中
final String key="redis:test:2";
ListOperations listOperations=redisTemplate.opsForList();
for (Person p:list){
//往列表中添加数据—从队尾中添加
listOperations.leftPush(key, p);
}
//获取Redis中List的数据—从队头中遍历获取,直到没有元素为止
log.info("--获取Redis中List的数据-从队头中获取--");
Object res=listOperations.rightPop(key);
Person resP;
while (res! =null){
resP= (Person) res;
log.info("当前数据:{} ", resP);
res=listOperations.rightPop(key);
}
}
3.集合
用于存储具有相同类型或特性的不重复的数据。即Redis中的集合Set存储的数据是唯一的,其底层的数据结构是通过哈希表来实现的,所以其添加、删除、查找操作的复杂度均为O(1)。
Redis的集合类型确实可以保证存储的数据是唯一、不重复的。在实际互联网应用中,Redis的Set类型常用于解决重复提交、剔除重复 ID等业务场景
//集合类型
@Test
public void three() throws Exception{
//构造一组用户姓名列表
List<String> userList=new ArrayList<>();
userList.add("debug");
userList.add("jack");
userList.add("修罗");
userList.add("大圣");
userList.add("debug");
userList.add("jack");
userList.add("steadyheart");
userList.add("修罗");
userList.add("大圣");
log.info("待处理的用户姓名列表:{} ", userList);
//遍历访问,剔除相同姓名的用户并塞入集合中,最终存入缓存中
final String key="redis:test:3";
SetOperations setOperations=redisTemplate.opsForSet();
for (String str:userList){
setOperations.add(key, str);
}
//从缓存中获取用户对象集合
Object res=setOperations.pop(key);
while (res! =null){
log.info("从缓存中获取的用户集合-当前用户:{} ", res);
res=setOperations.pop(key);
}
}
4. 有序集合
SortedSet可以通过底层的Score(分数/权重)值对数据进行排序,实现存储的集合数据既不重复又有序,可以说其包含了列表List、集合Set的特性。
Redis的有序集合类型SortedSet确实可以实现数据元素的有序排列。默认情况下,SortedSet的排序类型是根据得分Score参数的取值从小到大排序,如果需要倒序排列,则可以调用reverseRange()方法即可!
//有序集合
@Test
public void four() throws Exception{
//构造一组无序的用户手机充值对象列表
List<PhoneUser> list=new ArrayList<>();
list.add(new PhoneUser("103",130.0));
list.add(new PhoneUser("101",120.0));
list.add(new PhoneUser("102",80.0));
list.add(new PhoneUser("105",70.0));
list.add(new PhoneUser("106",50.0));
list.add(new PhoneUser("104",150.0));
log.info("构造一组无序的用户手机充值对象列表:{}", list);
//遍历访问充值对象列表,将信息塞入Redis的有序集合中
final String key="redis:test:4";
//因为zSet在add元素进入缓存后,下次就不能进行更新了,因而为了测试方便
//进行操作之前先清空该缓存(实际生产环境中不建议这么使用)
redisTemplate.delete(key);
//获取有序集合SortedSet操作组件ZSetOperations
ZSetOperations zSetOperations=redisTemplate.opsForZSet();
for (PhoneUser u:list){
//将元素添加进有序集合SortedSet中
zSetOperations.add(key, u, u.getFare());
}
//前端获取访问充值排名靠前的用户列表
Long size=zSetOperations.size(key);
//从小到大排序
Set<PhoneUser> resSet=zSetOperations.range(key,0L, size);
//从大到小排序
//Set<PhoneUser> resSet=zSetOperations.reverseRange(key,0L, size);
//遍历获取有序集合中的元素
for (PhoneUser u:resSet){
log.info("从缓存中读取手机充值记录排序列表,当前记录:{} ",u);
}
}
5. 哈希Hash存储
Redis的哈希存储跟Java的HashMap数据类型有点类似,其底层数据结构是由Key-Value组成的映射表,而其Value又是由Filed-Value对构成,特别适用于具有映射关系的数据对象的存储。
在实际互联网应用,当需要存入缓存中的对象信息具有某种共性时,为了减少缓存中Key的数量,应考虑采用Hash哈希存储。
/Hash哈希存储
@Test
public void five() throws Exception{
//构造学生对象列表和水果对象列表
List<Student> students=new ArrayList<>();
List<Fruit> fruits=new ArrayList<>();
//往学生集合中添加学生对象
students.add(new Student("10010", "debug", "大圣"));
students.add(new Student("10011", "jack", "修罗"));
students.add(new Student("10012", "sam", "上古"));
//往水果集合中添加水果对象
fruits.add(new Fruit("apple","红色"));
fruits.add(new Fruit("orange","橙色"));
fruits.add(new Fruit("banana","黄色"));
//分别遍历不同的对象列表,并采用Hash哈希存储至缓存中
final String sKey="redis:test:5";
final String fKey="redis:test:6";
//获取Hash存储操作组件HashOperations,遍历获取集合中的对象并添加进缓存中
HashOperations hashOperations=redisTemplate.opsForHash();
for (Student s:students){
hashOperations.put(sKey,s.getId(),s);
}
for (Fruit f:fruits){
hashOperations.put(fKey,f.getName(),f);
}
//获取学生对象列表与水果对象列表
Map<String,Student> sMap=hashOperations.entries(sKey);
log.info("获取学生对象列表:{} ",sMap);
Map<String,Fruit> fMap=hashOperations.entries(fKey);
log.info("获取水果对象列表:{} ",fMap);
//获取指定的学生对象
String sField="10012";
Student s= (Student) hashOperations.get(sKey,sField);
log.info("获取指定的学生对象:{} -> {} ",sField,s);
//获取指定的水果对象
String fField="orange";
Fruit f= (Fruit) hashOperations.get(fKey,fField);
log.info("获取指定的水果对象:{} -> {} ",fField,f);
}