需求:项目中需要从两个地方获取数据源,我使用的数据源是redis+solr,solr中保存的是以前的数据,redis中保存的是最新数据,每天有job将redis中的数据在solr中创建索引。如何从两者之中取分页数据?
设计思路:设计三个接口:
a,从redis获取数据接口:redisService
b,从solr中获取数据接口:solrService
c,提供给外部调用数据接口:dataService
我主要是想分享如何从两个数据源获取分页数据,因为从redis中可以直接根据sort(String key,SortingParams param)获取分页数据,solr中可以直接根据solr提供的方法获取分页数据,(都是可以根据开始条数和条数获取数据),很简单,我这里就单写下如何从这两者中综合获取数据,
请大家记得,redis中的数据是当天数据,可以按照一定的方式排序获取,solr中的数据为非当天数据,也可以按照一定的方式排序;
下面我写下DataService中的实现方法以及需要用到的工具类:
一、分页需要用到的工具类:
/**
* Copyright (c) 2013-2013 All Rights Reserved.
*/
package org.laoyao.util;
/**
*
* 功能描述: 翻页相关的功能
* @version 1.0.0 date 2013-06-27 下午3:52:18
*/
public class PageUtil {
public static final int PAGE_SIZE = 10;
public static int getPageNumber(int counts) {
return (counts == 0) ? 0 : (int) (counts % PAGE_SIZE == 0 ? counts / PAGE_SIZE : (counts / PAGE_SIZE + 1));
}
/**
* 功能描述:通过页号和每页记录数得到开始记录号
* @param
* @return
*/
public static int getBeginNum(int pageNum, int pageSize) {
return (pageNum - 1) * pageSize + 1;
}
/**
* 功能描述:通过页号和每页记录数得到结束记录号
* @param
* @return
*/
public static int getEndNum(int pageNum, int pageSize) {
return pageNum * pageSize;
}
}
上面是一个工具类,可以根据数量计算分多少页,以及取某一页的开始和结束记录号,下面写主要的业务逻辑:
public class DataServiceImpl implements DataService {
@Override
public Object supplierData(int pageNum, int pageSize) {
List<Object> redisObjs = null;
List<Object> solrObjs = null;
List<Object> result = null;
// 获取取数据的开始条数和条数
Map<String, Integer> splitPageMap = getSplitPageNumbers(pageNum, pageSize);
int redisBeginNum = splitPageMap.get("redisBeginNum");
int redisCount = splitPageMap.get("redisCount");
int solrBeginNum = splitPageMap.get("solrBeginNum");
int solrCount = splitPageMap.get("solrCount");
if (redisCount != 0) {
// 调用取数据接口,从redis中获取评价数据
redisObjs = redisService.getDataFromRedis(int redisBeginNum,int redisCount);
}
if (solrCount != 0) {
// 调用数据接口,从solr中获取评价数据
solrObjs = solrService.getDataFromRedis(int solrBeginNum,int solrCount);
}
result = new ArrayList<Object>();
result.addAll(redisObjs);
result.addAll(solrObjs);
return result;
}
/**
* 获取分页的起始条数
*
* @return
*/
private Map<String, Integer> getSplitPageNumbers(int pageNum, int pageSize) {
Map<String, Integer> splitPageMap = new HashMap<String, Integer>();
int redisBeginNum = 0; // 从redis中获取数据的开始记录号
int redisCount = 0; // 从redis中获取数据的条数
int solrBeginNum = 0; // 从solr中获取数据的开始记录号
int solrCount = 0; // 从solr中获取数据的条数
int count = 5; // 此处count为符合条件的数据在redis中有多少条,我先写死,不影响思路
int beginNum = PageUtil.getBeginNum(pageNum, pageSize) - 1; // 调用数据方需要的数据起始记录号
int endNum = PageUtil.getEndNum(pageNum, pageSize) - 1; // 调用数据方需要的数据结束记录号
if (beginNum > count) {
// 此种情况下,只从solr中取数据,开始条数和所取数据条数为:
solrBeginNum = beginNum - count;
solrCount = pageSize;
} else if (endNum < count) {
// 此种情况下只从redis中取数据
redisBeginNum = beginNum;
redisCount = pageSize;
} else if (beginNum <= count && endNum >= count) {
// 此种情况从solr+redis取数据
redisBeginNum = beginNum;
redisCount = count - beginNum;
solrBeginNum = 0;
if (beginNum == count) {
solrCount = pageSize;
} else {
solrCount = pageSize - redisCount;
}
}
splitPageMap.put("redisBeginNum", redisBeginNum);
splitPageMap.put("redisCount", redisCount);
splitPageMap.put("solrBeginNum", solrBeginNum);
splitPageMap.put("solrCount", solrCount);
return splitPageMap;
}
}
主要的分页逻辑就在方法getSplitPageNumbers中,大家看过后如果发现问题可以告诉我,不胜感激。