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)