Dataway介紹
Dataway 是基於 DataQL 服務聚合能力,為應用提供的一個接口配置工具。使得使用者無需開發任何代碼就配置一個滿足需求的接口。 整個接口配置、測試、冒煙、發布。一站式都通過 Dataway 提供的 UI 界面完成。UI 會以 Jar 包方式提供並集成到應用中並和應用共享同一個 http 端口,應用無需單獨為 Dataway 開辟新的管理端口。
這種內嵌集成方式模式的優點是,可以使得大部分老項目都可以在無侵入的情況下直接應用 Dataway。進而改進老項目的迭代效率,大大減少企業項目研發成本。
Dataway 工具化的提供 DataQL 配置能力。這種研發模式的變革使得,相當多的需求開發場景只需要配置即可完成交付。 從而避免了從數據存取到前端接口之間的一系列開發任務,例如:Mapper、BO、VO、DO、DAO、Service、Controller 統統不在需要。
大家好在《在 Spring Boot 中使用 Dataway 配置數據查詢接口》文章中,我們介紹了如何使用。Dataway 來配置接口避免開發工作。這篇文章來介紹一下如何配置分頁查詢接口。
眾所周知分頁查詢是絕大部分項目都無法繞過的問題,Dataway既然可以提供數據接口的配置化。那么自然也就無法繞過分頁問題,好在 Dataway 在最初版本發布的時候就已經可以實現分頁查詢。現在我就帶領大家看一看 Dataway 是怎樣實現分頁查詢的。
DataQL分頁查詢文檔:https://www.hasor.net/web/dataql/fragment/sql/execute.html#id5 在DataQL 中開啟分頁查詢的官方手冊在這里: 想要仔細研究的可以去這里查閱。
原理
首先講一下分頁原理,提到分頁通常包含兩種方式:真分頁、假分頁
- 真分頁:是指數據在從數據庫中查詢回來的數據就已經是分頁之后的數據,程序無需在做過多的處理。這種一般適用於表的數據比較大的情況。
- 假分頁:是指數據會首先全部加載到程序中,然后通過程序代碼返回其中一段數據。這種模式比較適用於數據不經常變化且數據量不多的場景。
在一般場景中假分頁的使用越來越少,很多能力可以直接由前端組建直接實現。接下來我們就討論一下,怎樣實現真分頁。
真分頁,通常會考慮數據庫兼容的問題。例如:下面 Myql 和 Oracle 對於數據庫分頁的 SQL 語句
Mysql:
select * from user_info limit m,n
Oracle:
SELECT * FROM ( SELECT TMP_PAGE.*, ROWNUM ROW_ID FROM ( select * from user_info ) TMP_PAGE) WHERE ROW_ID > m AND ROW_ID <= n");
Dataway 也是采用這一種 SQL 改寫的方式,Dataway 在實現 SQL 語句改寫的時候采用數據庫方言,方言的SQL語句改寫上,參考了成熟的開源框架 MyBatis 分頁插件 PageHelper
因此理論上可以直接兼容下列數據庫。
方言版本 |
兼容的數據庫 |
DB2 |
DB2 |
HsqlDB |
H2、HsqlDB、PostgreSQL、Phoenix |
Informix |
Informix |
Mysql |
Mysql、Mariadb、SQLite、HerdDB |
Oracle |
Oracle |
SqlServer2012 |
SqlServer2012、Derby |
分頁查詢
首先我們延續上一篇文章中 “user_info” 表的查詢例子。 首先我們知道 DataQL 默認是不開啟分頁的,要想實現分頁需要我們自己計算 start/limit 然后通過參數的形式傳給 SQL。
要想 DataQL 默認開啟分頁需要加入一個 Hint 將其打開:hint FRAGMENT_SQL_QUERY_BY_PAGE = true
需要在這里提醒大家的是,DataQL 的 Hint 是全局生效的,而且只能在編寫 QL 查詢的最前面聲明。這就意味着,一旦開啟了分頁查詢。整個 QL 查詢中所有 SQL 相關的查詢操作都會成為分頁模式。
開啟分頁模式之后,通過 SQL 獲取數據將會分為4個階段:
- 定義分頁SQL
- 創建分頁查詢對象
- 設置分頁信息
- 執行分頁查詢
第一步:還是定義 SQL,只不過這次我們要加上一個 hint 表示要開啟分頁查詢。
// 步驟 1:定義分頁SQL hint FRAGMENT_SQL_QUERY_BY_PAGE = true var dimSQL = @@sql(userName)<% select * from user_info where `name` like concat('%',#{userName},'%') %>;
第二步:獲取這個 SQL 定義的分特查詢對象
// 步驟 2:獲取分頁對象 var queryPage = dimSQL(${userName});
第三步:設置分頁信息
// 步驟 3:設置分頁信息 run pageQuery.setPageInfo({ "pageSize" : 5, // 頁大小 "currentPage" : 3 // 第3頁 });
第四步:執行SQL查詢,獲取到分頁數據
下列是我們數據庫中的用戶數據,可以看到每頁5條第三頁正式我們想要的數據。(請注意:DataQL 的分頁頁碼是 從0 開始的)
create table user_info ( id int auto_increment primary key, name varchar(128) null, sex int null ); // page 0 INSERT INTO example.user_info (id, name, sex) VALUES (1, 'user-1', 1); INSERT INTO example.user_info (id, name, sex) VALUES (2, 'user-2', 0); INSERT INTO example.user_info (id, name, sex) VALUES (3, 'user-3', 1); INSERT INTO example.user_info (id, name, sex) VALUES (4, 'user-4', 0); INSERT INTO example.user_info (id, name, sex) VALUES (5, 'user-5', 1); // page 1 INSERT INTO example.user_info (id, name, sex) VALUES (6, 'user-6', 0); INSERT INTO example.user_info (id, name, sex) VALUES (7, 'user-7', 1); INSERT INTO example.user_info (id, name, sex) VALUES (8, 'user-8', 0); INSERT INTO example.user_info (id, name, sex) VALUES (9, 'user-9', 1); INSERT INTO example.user_info (id, name, sex) VALUES (10, 'user-10', 0); // page 2 INSERT INTO example.user_info (id, name, sex) VALUES (11, 'user-11', 1); INSERT INTO example.user_info (id, name, sex) VALUES (12, 'user-12', 0); INSERT INTO example.user_info (id, name, sex) VALUES (13, 'user-13', 1); INSERT INTO example.user_info (id, name, sex) VALUES (14, 'user-14', 0); INSERT INTO example.user_info (id, name, sex) VALUES (15, 'user-15', 1); // page 3 INSERT INTO example.user_info (id, name, sex) VALUES (16, 'user-16', 0); INSERT INTO example.user_info (id, name, sex) VALUES (17, 'user-17', 1); INSERT INTO example.user_info (id, name, sex) VALUES (18, 'user-18', 0); INSERT INTO example.user_info (id, name, sex) VALUES (19, 'user-19', 1); INSERT INTO example.user_info (id, name, sex) VALUES (20, 'user-21', 0); // page 4 INSERT INTO example.user_info (id, name, sex) VALUES (21, 'user-22', 1); INSERT INTO example.user_info (id, name, sex) VALUES (22, 'user-23', 0); INSERT INTO example.user_info (id, name, sex) VALUES (23, 'user-24', 1); INSERT INTO example.user_info (id, name, sex) VALUES (24, 'user-25', 0); INSERT INTO example.user_info (id, name, sex) VALUES (25, 'user-26', 0); // page 5 INSERT INTO example.user_info (id, name, sex) VALUES (26, 'user-27', 1); INSERT INTO example.user_info (id, name, sex) VALUES (27, 'user-28', 0); INSERT INTO example.user_info (id, name, sex) VALUES (28, 'user-29', 1); INSERT INTO example.user_info (id, name, sex) VALUES (29, 'user-30', 0); INSERT INTO example.user_info (id, name, sex)