C/S框架-WebService架构下分页查询数据解决方案
使用WebService架构开发的数据库应用软件不适合大批量下载数据,不是技术不能实现,而是广域网络太娇情!若有光纤的速度,一次Download 100W记录也不算多啊!网速限制只能从技术上突破,优化下载速度是使用WebService构架开发系统必须重视的工作,我们可以从下面几部分入手:
1. 数据分页查询。
2. 数据压缩。
3. 优化后台程序,包括数据层逻辑处理及存储过程优化。
4. WebService安全,防止黑客攻击。
5. 限制用户查询次数。
6. 服务器硬件配置,配置高与查数据成正比。
本文详细介绍数据分页查询,下图是PageCache逻辑结构:
程序界面:
数据查询界面,四个蓝色按钮分别是:最前页,上一页,下一页,最后页,下图是查询了第一页的数据。
查询最后一页的数据,请看缓存进度。
接口/具体类介绍:
IMyDataView:数据视图接口,已扩展了Dev GridView,通过这个接口可以扩展TreeView显示数据,如何展示数据在SetDataSource方法内实现。
IMyPageDataCache:数据分页查询业务逻辑接口。
MyDataTablePageCache:类,使用DataTable缓存数据的类,如果您用到实体类ORM, 扩展为IList即可。
ISupportPageSearch:支持分页查询的接口,该接口用于具体的业务逻辑类(BLL),如SO,销售订单业务逻辑。
MyTestBLL:用于测试的业务逻辑类,实现ISupportPageSearch接口,该类模拟销售订单业务逻辑查询数据。
接口源码:
/// <summary>
/// 缓存数据接口
/// </summary>
public interface IMyPageDataCache
{
/// <summary>
/// 每页记录数
/// </summary>
int PageSize { get; set; }
/// <summary>
/// 本次查询总页数
/// </summary>
int PageCount { get; }
/// <summary>
/// 当前页号
/// </summary>
int CurrentPage { get; }
/// <summary>
/// 已缓存的页数
/// </summary>
int CachedPage { get; }
/// <summary>
/// 按页号取出缓存数据
/// </summary>
/// <param name="pageNo">页号</param>
/// <returns></returns>
DataTable GetPageData(int pageNo);
/// <summary>
/// 初始化缓存数据管理器,第一次搜索时调用此方法。
/// </summary>
/// <param name="searchConditions"></param>
void InitializeSearch(object[] searchConditions);
/// <summary>
/// 清空缓期数据
/// </summary>
void ClearCache();
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
/// <summary>
/// 支持按页搜索的接口,由具体的BLL层实现, 如:SO,Customer
/// </summary>
public interface ISupportPageSearch
{
/// <summary>
/// 搜索指定页面的数据
/// </summary>
/// <param name="searchConditions">查询条件(数组)</param>
/// <param name="pageNo">页号</param>
/// <param name="pageSize">每页记录数</param>
/// <returns></returns>
DataTable SearchByPage(object[] searchConditions, int pageNo, int pageSize);
/// <summary>
/// 获取本次搜索返回的页数
/// </summary>
/// <param name="searchConditions">查询条件(数组)</param>
/// <returns></returns>
int GetPageCount(object[] searchConditions, int pageSize);
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
/// <summary>
/// 数据视图接口
/// </summary>
public interface IMyDataView
{
/// <summary>
/// 设置数据源
/// </summary>
/// <param name="dataSource">数据源</param>
void SetDataSource(object dataSource);
}
分页查询存储过程:
这个SP效率不高,您可以写高效率的SP,当然条件字段必须建立索引大大提高查询速度。
ALTER PROCEDURE [dbo].[usp_SearchSO]
@BeginDate DATETIME,
@EndDate DATETIME,
@PageNo INT,
@PageSize INT,
@IsGetPageCount CHAR(1) --Y/N
AS
BEGIN
/******************************************************
说明:按页查询数据
原创:C/S框架网www.csframework.com
usp_SearchSO '
*******************************************************/
IF @PageNo=0 SET @PageNo=1
IF @PageSize=0 SET @PageSize=1
--------------------------------------------------------------------
IF (@IsGetPageCount='Y')
BEGIN
PRINT '取本次查询返回的页数'
DECLARE @ROWS INT,@PAGE_COUNT INT
SET @PAGE_COUNT=0
SELECT @ROWS=COUNT(ISID) FROM tb_SO WHERE DocDate BETWEEN @BeginDate AND @EndDate
IF (@ROWS>0)
BEGIN
SET @PAGE_COUNT=@ROWS/@PageSize
IF (@ROWS % @PageSize)>0 SET @PAGE_COUNT=@PAGE_COUNT+1
END
SELECT @PAGE_COUNT AS PAGE_COUNT
RETURN
END
-----------------------------------------------------------------------
DECLARE @SQL NVARCHAR(2000),@WHERE NVARCHAR(100),@PriorPageMaxID INT,@PriorPageRows INT
--DROP TABLE ##PRIOR_PAGE_MAX_ID
CREATE TABLE ##PRIOR_PAGE_MAX_ID(MAX_ID INT)
SET @PriorPageRows=(@PageNo-1)*@PageSize
SET @WHERE=' WHERE CONVERT(VARCHAR,DocDate,112) BETWEEN '+CONVERT(VARCHAR,@BeginDate,112) + ' AND '+CONVERT(VARCHAR,@EndDate,112)
SET @SQL=' INSERT INTO ##PRIOR_PAGE_MAX_ID SELECT MAX(T.ISID) AS MAX_ID FROM (SELECT TOP '+CAST(@PriorPageRows AS VARCHAR)+' ISID FROM tb_SO '+@WHERE+') T '
PRINT @SQL
EXEC(@SQL)
SELECT @PriorPageMaxID=ISNULL(MAX_ID,0) FROM ##PRIOR_PAGE_MAX_ID
SET @SQL=' SELECT TOP '+CAST(@PageSize AS VARCHAR)+' * FROM tb_SO '+@WHERE
SET @SQL=@SQL+' AND ISID>'+CAST(@
-----------------------------------------------------------------------------
PRINT @SQL
EXEC(@SQL)
DROP TABLE ##PRIOR_PAGE_MAX_ID
END
如转载请注明出处:C/S框架网 www.csframework.com
Source Code for VIP:
开发环境:VS2008+DevExpress 9.24
数据库在Debug目录下。
扫一扫加微信