在我们开发项目的过程中,经常会对数据做分页展示,如果每次请求都去查询数据库,当访问量增大时,势必会加重数据库的负载,降低数据库性能。然而,有些数据的是极少变动的,或者说变动的频率不是很高,这时如果将这些数据进行缓存,不仅可以提高程序性能,还能降低数据库的负载。下面就给出高并发下的分页数据缓存方案。
一、需要了解的一些知识点
1、redis的hmset(key, value)方法,将key值设置为value,value是map类型的数据结构
2、redis的hgetAll(key)方法,获取key的值,改值的类型为map类型的
3、关键字synchronized
4、key值包含的一些关键信息,前缀+当前的页数+每页数据的大小等
二、代码实现
/* (non-Javadoc)
* 默认为60秒刷新一次;采用加锁模式应对高并发
*/
@Override
public Page<StrategySummary> getAdvisorStrategys(AdvisorCondition condition) throws IOException{
Pageable pageable=condition.getPage();
int currentPage = pageable.getPageNumber();
int pageSize = pageable.getPageSize();
Map<String,String> result=RedisUtil.getMap("advisor:"+condition.getId()+"_number:"+currentPage+"_size:"+pageSize, MARKET);
if (result!=null&&result.size()>0) {
List<StrategySummary> dataList=JsonUtils.toJavaBeanList(result.get("data"), new TypeReference<List<StrategySummary>>() {});
long total=Long.valueOf(result.get("total"));
return new PageImplBean<StrategySummary>(dataList, pageable, total);
} else {
Page<StrategySummary> page=null;
synchronized (MobileAppServiceImpl.class) { //当首个线程将数据缓存后,后面的线程需再次检查,防止重复查询数据库和缓存数据
int count = 0;
for (int i = 0; i < 3; i++) { //取3次,防止获取失败
Map<String,String> map =RedisUtil.getMap("advisor:"+condition.getId()+"_number:"+currentPage+"_size:"+pageSize, MARKET);
if (map==null||map.size()==0) {
continue;
}
if (map!=null&&map.size()>0) {
count++;
break;
}
}
if (count==0) {
page= mobileAppDao.getAdvisorStrategys(condition);
List<StrategySummary> dataList=page.getContent();
long total=page.getTotalElements();
if(dataList.size()>0){
Map<String, String> map=new HashMap<String,String>();
map.put("data", JsonUtils.toJsonString(dataList));
map.put("total", String.valueOf(total));
RedisUtil.setMapWithExpire("advisor:"+condition.getId()+"_number:"+currentPage+"_size:"+pageSize, map, MARKET);
}
}else{
Map<String,String> map =RedisUtil.getMap("advisor:"+condition.getId()+"_number:"+currentPage+"_size:"+pageSize, MARKET);
List<StrategySummary> dataList=JsonUtils.toJavaBeanList(map.get("data"), new TypeReference<List<StrategySummary>>() {});
long total=Long.valueOf(map.get("total"));
page= new PageImplBean<StrategySummary>(dataList, pageable, total);
}
}
return page;
}
}