redis的分页查询利用到了sortset 和 hash的两个数据类型,这两个互相配合使用才能完美的完成分页,思想都在都在代码中
1.初始逻辑
@Override
public List<User> selectAll() {
long page = 2;
long pageSize = 4;
String key = "user_key_";
List<User> users = new ArrayList<>();
if (!redisTemplate.hasKey(key)) {
users = userMapper.selectAll();
for (User user : users) {
//初始化user_key的索引,利用sortset来保存hk每个对象的hk
redisTemplate.opsForZSet().add("sortId", key + user.getId(), user.getId());
//利用hash来保存user,这里的hk要和sortset保存的value一致,后续分页的时候有用
redisTemplate.opsForHash().put(key, key + user.getId(), user);
}
return users;
}else {
//获得最后一个对应的member,用于获得最大的分数
Set<String> sortId = redisTemplate.opsForZSet().reverseRange("sortId", 0, 0);
String hkey = sortId.iterator().next();
//根据member获得最大分值
Double maxScore = redisTemplate.opsForZSet().score("sortId", hkey);
// 分页取数据
Set<String> sets = redisTemplate.opsForZSet().rangeByScore("sortId",0,maxScore,(page-1)*pageSize,page*pageSize);
List list = new ArrayList(sets);
System.out.println(sets);
//批量根据获得的key批量获取
users = redisTemplate.opsForHash().multiGet(key,list);
return users;
}
}
}
2.优化后
1.创建RedisUtil
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String,String> redisTemplate;
/**
* 获得最大分数
* @param key
* @return
*/
public Double sMaxScore(String key){
//获得最后一个对应的member,用于获得最大的分数
Set<String> sortId = redisTemplate.opsForZSet().reverseRange(key, 0, 0);
String hkey = sortId.iterator().next();
//根据member获得最大分值
Double maxScore = redisTemplate.opsForZSet().score(key, hkey);
return maxScore;
}
/**
* 分页获取成员
* @param key
* @param min 最小分数
* @param max 最大分数
* @param pageStart
* @param pageSize
* @return
*/
public List sRangeByScore(String key,Double min,Double max,Long pageStart,Long pageSize){
// 分页取数据
Set<String> sets = redisTemplate.opsForZSet().rangeByScore(key,min,max,(pageStart-1)*pageSize,pageStart*pageSize);
List list = new ArrayList(sets);
return list;
}
/**
* 批量获得数据
* @param key
* @param hkeys
* @return
*/
public List hMultiGet(String key , List hkeys){
return redisTemplate.opsForHash().multiGet(key, hkeys);
}
}
2.selectAll()方法
@Override
public List<User> selectAll() {
long page = 1;
long pageSize = 30;
String key = "user_key_";
List<User> users = null;
if (redisTemplate.hasKey(key)) {
//获得最大分值
Double maxScore = redisUtil.sMaxScore("sortId");
// 分页取数据
List list = redisUtil.sRangeByScore("sortId",0.0,maxScore,page,pageSize);
users =redisUtil.hMultiGet(key,list);
return users;
}else {
users = userMapper.selectAll();
for (User user : users) {
//初始化user_key的索引
redisTemplate.opsForZSet().add("sortId", key + user.getId(), user.getId());
redisTemplate.opsForHash().put(key, key + user.getId(), user);
}
return users;
}
}
有不足的地方请多多指教