用Java實現異構數據庫的高效通用分頁查詢功能


不同數據庫的分頁查詢語句有着較大區別,其中MySQL數據的limit offset語法最為簡單,而SQL Server數據庫和Oracle數據庫的分頁就比較復雜了。

網上常見的SQL Server和Oracle數據庫的分頁語句都或多或少對表結構有要求,比如必須有遞增的主鍵ID等。

 

當我們不能確定所連查詢數據表的表結構(比如表是客戶動態提供的)時,如何以一種通用且高效的方式在不同數據庫上實現分頁查詢功能呢?

 

解決方案1:使用JDBC的通用分頁功能

第一步:利用java.sql.Statement#setMaxRows方法,設置本次查詢的最大記錄數。

第二步:查詢結束后,利用java.sql.ResultSet#absolute方法,跳過前面不屬於查詢頁的記錄。

這種方法的優點是簡單通用。它的缺點也很明顯,就是性能問題,比如查詢最后一頁數據時,JDBC實現原理是先查出所有數據,然后跳過前面頁的數據,性能損傷很大。

如果你確定你所處的業務場景,用戶通常只會觸發前幾頁的查詢(比如搜索場景:如果前幾頁沒有自己想要的東西,通常是縮小查詢范圍重新搜索,而不是逐頁往后去查找),那么這種簡單且通用的方法不失為一種性價比較高的選擇。

 

解決方案2:使用各類數據庫的通用分頁SQL語句

這是Hibernate的解決思路,由於最終將向數據庫發送的是數據庫相關的特定分頁SQL語句,數據庫有充分的信息進行優化,且最終只返回一頁的記錄。

現在問題的關鍵在於各類數據庫的通用(對表結構沒有限制)分頁查詢語句格式是怎樣的呢?

下面將一一介紹。

注:為了便於舉例,下面的SQL語句均實現的是查詢一張名為test表中的column1、column2、column3字段的值,查詢時設置了基於column1的過濾條件,同時可選是否基於column1排序。column1、column2、colum3沒有任何特殊性,讀者可以將下述SQL格式套用在任何表結構上,同時可以豐富過濾條件。

MySQL/MariaDB數據庫(不排序)

SELECT column1, column2, column3 FROM test WHERE column1 = ? LIMIT 1000 OFFSET 0

MySQL/MariaDB數據庫(排序)

SELECT column1, column2, column3 FROM test WHERE column1 = ? ORDER BY column1 ASC LIMIT 1000 OFFSET 0

SQL Server數據庫(不排序)

SELECT column1, column2, column3 FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS ROWNUM,* FROM test WHERE column1 = ?)t WHERE t.ROWNUM > 0 AND t.ROWNUM <= 1000

SQL Server數據庫(排序)

SELECT column1, column2, column3 FROM (SELECT ROW_NUMBER() OVER ( ORDER BY column1 ASC) AS ROWNUM,* FROM test WHERE column1 = ?)t WHERE t.ROWNUM > 0 AND t.ROWNUM <= 1000

 Oracle/達夢數據庫(不排序)

SELECT column1, column2, column3 FROM (SELECT ROWNUM RN,t.* FROM (SELECT * FROM test WHERE column1 = ?)t WHERE ROWNUM <= 1000) WHERE RN > 0

Oracle/達夢數據庫(排序)

SELECT column1, column2, column3 FROM (SELECT ROWNUM RN,t.* FROM (SELECT * FROM test WHERE column1 = ? ORDER BY column1 ASC)t WHERE ROWNUM <= 1000) WHERE RN > 0

 這種方法的優點是效率高,缺點是需要學習不同種類的數據庫的通用分頁SQL語句格式。

希望本文總結的這幾種常見數據庫的通用分頁SQL格式能夠覆蓋你的需求,為你帶來幫助。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM