一个分页的小例子(从两个数据源获取数据)

需求:项目中需要从两个地方获取数据源,我使用的数据源是redis+solr,solr中保存的是以前的数据,redis中保存的是最新数据,每天有job将redis中的数据在solr中创建索引。如何从两者之中取分页数据?

设计思路:设计三个接口:

a,从redis获取数据接口:redisService

b,从solr中获取数据接口:solrService

c,提供给外部调用数据接口:dataService

194227_rkeP_858241.png

我主要是想分享如何从两个数据源获取分页数据,因为从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中,大家看过后如果发现问题可以告诉我,不胜感激。


转载于:https://my.oschina.net/u/858241/blog/308182

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
asp的七种分页方法! 简单 实用 是有点乱 ASP中七种实现分页显示的方法 MS Visual InterDev6.0中七种实现分页显示的方法 我们在编制与数据库有关的Web网页时,由于要显示的数据量巨大,常常面临一个数据记录分页显示的问题。 -------------------------------------------------------------------------------- 在微软的ASP编程体系中,ADO对象的建立,使得从网页访问数据库成为一件易事,特别是ADO的Recordset对象使得控制数据的输出显示更为方便、自由。而在Visual InterDev6.0(以下简称VI6.0)中,由于Script Object Model(以下简称SOM)、Design-Time Control(以下简称DTC)以及Data Environment Object Model(以下简称DEOM)等对象模型的引入,使网页对数据库的访问设计显得更为方便。 因为主题方面的原因,关于数据库的连接,下文只给出代码和简要注释,而把重点放在如何利用Recordset对象(或控件)实现数据记录的分页显示方面。根据我的理解,分页显示的关键就在于对ADO的Recordset对象或DTC(设计时控件)的Recordset控件的属*和方法的熟练把握上。 这七种分页显示的方法概括起来说分四类: 第一、二种我暂取名叫“纯ASP法”,这也是国内的ASP网站上用得最多的方法,它们的区别仅在实现技巧的不同。这两种方法的实现最易理解,用到的对象概念也最少,对开发环境的要求也最低(只要记事本就行)。可以说,这两种方法的实质还是CGI的编程思想,只是在程序中引入了ADO对象而已。 第四、五种暂取名叫“SOM的DHTML法”。这两种方法要求在VI6.0的环境下,利用微软提出的脚本对象模型(Script Object Model)和DHTML中Table对象的与数据库绑定的新特*(许多书和文章只介绍了DHTML的CSS特*在样式设计中的运用而忽略介绍其数据绑定特*),实现在客户端控制翻页。但它要求用户的浏览器必须是支持DHTML,如:Microsoft Internet Explorer 4.0及以上的版本。 第六种暂取名叫“SOM服务器端法”。要求在VI6.0的环境下开发,它利用微软提出的脚本对象模型(Script Object Model)中的几个DTC控件:Recordset、PageObject、Grid等在服务器端(客户端)实现翻页控制。这是一种激动人心的、全新的编程方法,它把网页看成对象(这种对象模型和传统的DOM----document object model是有区别的:DOM只能控制客户端,而SOM可控制服务器端和客户端),它真正实现了网页的面向对象编程。但遗憾的是,也许是我个人能力有限,这种技术我个人认为还不是很成熟,比如,与浏览器的结合还不是很好,这将在后文详细说明。 第七种暂取名叫“DEOM法”。它也是利用了VI6.0中建立的数据环境对象模型(Data Environment Object Model)建立Recordset对象。这也是在网页编程上比较少见的新方法,与SOM模型相比,自有它的优点,这将在后文详述。 在后面所举的所有例子源代码,都可以直接拷贝使用,你甚至可以不懂其原理,只要把其中的粗斜体字部分换成相应自己的数据库名或字段名就可以了。 在开始详细介绍各种分页方法前,让我们先创建一个数据库:用Office97中的access自创一个Employee.mdb,其中建一个表emp,只设三个字段:emp ID,last name和first name。为什么这么简单,是因为我们关心的是怎样处理recordset的结果。 第一种:参数直接代入法。 这种方法是用手工建立Recordset对象,利用其pagesize(每页指定显示记录数),pagecount(总页码数)和absolutepage(当前页码数)属*来控制分页的输出。分页采用<href>直接带页码参数的方法来控制翻页。网页的名字为emp1.asp。源代码如下: <%//建立与employee.mdb数据库的连接。 Set conn = Server.CreateObject("ADODB.Connection") conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=employee.mdb" //建立emp表的Recordset对象实例rs。 Set rs = Server.CreateObject("ADODB.Recordset") rs.Open "emp", conn, 3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值