OEA ORM中的分頁支援

2021-09-23 21:27:22 字數 3749 閱讀 4599

本篇部落格主要描述分頁的常見技術方案,以及在 oea 框架中的分頁的應用及實現原理。

分頁的幾種方案

分頁是解決大資料量顯示的有效方法。根據分頁技術應用的位置不同,大致可以把分頁分為以下幾種:

介面層的分頁,類似於介面的虛擬化技術,是只顯示需要的資料的一種技術。oea 的 wpf 介面中目前已經實現了 ui 虛擬化,所以不再實現介面層分頁。

優點:* 簡單。許多控制項都支援在介面層直接進行分頁。

* 換頁時,響應快。(在 c/s 結構下使用這種方案,資料都已經到達客戶端,所以在分頁時不需要額外的資料查詢,響應速度較快。)

缺點:* 不用於太大的資料分頁。由於沒有減少網路傳輸,首次載入時較慢,需要把所有資料都傳輸到客戶端。

在實體層進行分頁操作的方案,很少會被使用。它是把查詢出來的資料,在伺服器端都轉換為實體,然後再找到具體頁的實體資料,其它的資料則直接丟棄。

優點:* 減少了首次的網路傳輸,對於客戶端而言,呼叫的是分頁的 api。

* 簡單。

* 通用性強,與資料庫無關,方案可以跨多種資料庫。

* 統計總行數不需要發起二次查詢。

缺點:* 占用記憶體,依然不能用於太大的資料分頁。

這種方案一般使用 idatareader 實現。查詢的 sql 依然是查詢所有的資料,但是在對查詢出的 idatareader 進行遍歷讀取每一行時,只讀取對應頁的資料,其它頁的資料則忽略。同時,遍歷到記錄集的最後一行,即可獲得資料的總行數。

優點:* 不占用大量記憶體。只把需要的資料讀取到記憶體中。

* 簡單。

* 通用性強,與資料庫無關,方案可以跨多種資料庫。

* 統計總行數不需要發起二次查詢。

缺點:* 查詢的 sql 會查詢很大的一張表。遍歷依然需要耗費一定的時間。

分頁的最終方案,自然是在資料庫中進行分頁。這也是大多數情況會選用的方案。

優點:* 效能最好。速度快、占用記憶體小。

* 統計行數時,往往需要重新發起查詢。

缺點:* 對於框架開發而言,要生成分頁相關的 sql,較麻煩。

* 方案與特定資料庫相關。通用性低。

雖然提到了這幾種不同層面的分頁方案。但是對應應用開發而言,資料庫的分頁是最常用的。只是在做 oea 框架開發時,由於要支援多種資料庫,所以需要在合適時採用不同的方案。同時,也不會考慮使用儲存過程來輔助分頁。

oea 分頁 - 應用層介面

在說明 oea 的分頁前。先介紹乙個 paginginfo 型別(老版本中,該類名為 pagerinfo),這關係到整個分頁方案的介面設計:

圖1 位於 common(原 hxy)程式集中的 paginginfo 型別

圖2 paginginfo 型別介面

在查詢資料時,我們指定了查詢的具體頁碼 pageindex、一頁所含資料行數 pagesize,就可以把該頁的資料顯示在介面上了。但是,在分頁時,往往要在介面中顯示乙個分頁尾,用於顯示當前頁號、所有頁數。所以在進行查詢的同時,往往還需要對結果集中所有資料的總行數進行統計,並把之與查詢出的實體列表資料一同返回。所以,我為 paginginfo 新增了額外的兩個屬性,isneedcount、totalcount,當 isneedcount 被設定為真時,框架在資料層進行查詢時,會把統計出來的總行數賦值給 totalcount。

oea 分頁 - 使用方法

下面以分頁查詢所有資料為例,簡單說明如何使用分頁查詢。先是應用層使用的**:

應用層需要構造 paginginfo,並指定需要統計行數。查詢後,直接使用 paginginfo.totalcount。(這種介面方案從 06 年使用至今,比較好用。

下面是 repository 型別上的公有介面:

最後,再實現該查詢對應的資料層即可:

可以看到,在資料訪問層的 orm 框架中,主要是在 iquery 條件型別上新增了乙個 paging 方法。使用這個方法指定了 paginginfo 後,即按給定的分頁資訊分頁查詢實體資料了。

oea 中的資料層分頁實現

oea 中用到的分頁有:介面層分頁、datareader 分頁、資料庫分頁。

目前,oea 已經支援了 sqlserver 2005+、oracle 10+、sqlce4+,但是框架的設計目標則是應對所有資料庫(接下來很可能需要對 mysql 進行支援)。這三種資料庫中,oea 只支援前兩種大型資料庫的資料庫分頁,主要是生成分頁 sql 進行查詢。

經過對比、挑選,我選用了一種可以在 sqlserver、oracle 上的一種通用方案,即使用 rownumber。例如,如果乙個 sql 查詢是:

select ...... from ...... order by ***x asc, yyyy desc

,則只需要把它轉換為以下格式就行了:

select * from (select ......, row_number() over(order by ***x asc, yyyy desc) _rownumber from ......) x where x._rownumber<10 and x._rownumber>5

同時,當需要統計總行數時,資料層會生成 select count(0) from ...... 的 sql 語句重新進行查詢,並把結果賦值給 paginginfo.totalcount,以及 entitylist.totalcount。

在 sqlce 中,並不支援 rownumber 函式。所以只能考慮使用 not in 的 sql 方案。其實在oea中,鑑於實現 not in 方案比較麻煩,所以決定暫時使用 datareader 完成 sqlce 的記憶體分頁。

提供 datareader 方案主要是簡單、同時還能與資料庫無關,解決跨庫問題。主要邏輯**如下:

///

///使用 idatareader 的記憶體分頁讀取方案。 

/// 

///注意!!! 

/// 

此方法中會釋放 reader。外層不能再用 using。 

///

///

///

每一行資料,會呼叫此方法進行調取。

///

分頁資訊。如果這個引數不為空,則使用其中描述的分頁規則進行記憶體分頁查詢。

public static void memorypaging(idatareader reader, action

rowreader, paginginfo paginginfo = null) 

using (reader) 

else 

break; 

} } 

} } 

} if (needcount)  }

通用,又簡單。

待改進點

目前實現上,可能存在的缺陷是:

希望大夥拍磚。

OEA ORM中的分頁支援

本篇部落格主要描述分頁的常見技術方案,以及在 oea 框架中的分頁的應用及實現原理。分頁的幾種方案 分頁是解決大資料量顯示的有效方法。根據分頁技術應用的位置不同,大致可以把分頁分為以下幾種 介面層的分頁,類似於介面的虛擬化技術,是只顯示需要的資料的一種技術。oea 的 wpf 介面中目前已經實現了 ...

Table Storage對分頁的支援

大家可能知道wcf data services最新版提供了server paging的功能,意即在服務期端對資料進行分頁,從而限制傳回客戶端的資料量。那麼windows azure table storage是否提供分頁功能呢?windows azure table storage本身就限制了客戶端...

SQL 分頁支援查詢

分頁支援查詢 select from select row number over order by id as row index from table as newtable where row index between startindex and endindex sql server 2...