• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

sql-paging: SQL分页查询方言类库。通过调用相关API,可快速将一个普通SQL转换为一个 ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

sql-paging

开源软件地址:

https://gitee.com/tenmg/sql-paging

开源软件介绍:

sql-paging

介绍

sql-paging是一个SQL分页查询方言类库,它原来是Sqltool的智能分页组件,后剥离出来作为独立项目,以供更多组件集成其能力。通过调用相关API,可快速将一个普通SQL转换为一个特定数据库的计数(COUNT)SQL或分页查询SQL。sql-paging通过内置的SQL分析工具类分析实际调用的SQL,让方言生成最优的计数(COUNT)SQL或分页查询SQL。

数据库支持

数据库支持版本方言实现类
MySQL1.0+MySQLPagingDialect
Oracle1.0+OraclePagingDialect
PostgreSQL1.0+PostgreSQLPagingDialect
SQLServer1.0+SQLServerPagingDialect

使用说明

以基于Maven项目为例

  1. pom.xml添加依赖,${sql-paging.version}为版本号,可定义属性或直接使用版本号替换
<!-- https://mvnrepository.com/artifact/cn.tenmg/sql-paging --><dependency>    <groupId>cn.tenmg</groupId>    <artifactId>sql-paging</artifactId>    <version>${sql-paging.version}</version></dependency>
  1. 调用PagingDialect.countSql方法获取计数SQL(以MySQL数据库为例)
String namedSql = "……";sqlMetaData sqlMetaData = SQLUtils.getSQLMetaData(namedSql);SQLPagingDialect dialect = MySQLPagingDialect.getInstance();String countSql = dialect.countSql(namedSql, sqlMetaData);……
  1. 调用PagingDialect.pageSql方法获取分页查询SQL(以MySQL数据库为例)
……try {    String pageSql = dialect.pageSql(con, namedSql, params, sqlMetaData, 20, 2);    ……} catch (SQLException e) {    // TODO Auto-generated catch block    e.printStackTrace();}……

API详解

countSql

用于根据实际查询的SQL自动生成计数SQL,完成对总数的统计,结合页容量可计算出总页数。根据对源SQL的分析和智能决策,生成计数SQL会去除不必要的列或者排序子句(ORDER BY),且不会引入不必要子查询,以达到最优性能。例如如下SQL:

SELECT  S.STAFF_ID,  S.STAFF_NAME,  S.DEPARTMENT_ID,  S.POSITION,  S.STATUSFROM STAFF_INFO SORDER BY S.STAFF_ID

并不是简单包裹子查询实现计数:

SELECT  COUNT(*)FROM (  SELECT    S.STAFF_ID,    S.STAFF_NAME,    S.DEPARTMENT_ID,    S.POSITION,    S.STATUS  FROM STAFF_INFO S  ORDER BY S.STAFF_ID) T

而是,不嵌套不必要的子查询,并去除不必要的排序子句:

SELECT  COUNT(*)FROM STAFF_INFO S

嗯,这的确是我们想要的样子。但如果情况复杂一点呢?比如,我们需要查询某段时间内用户的订单金额并按金额从大到小排序:

SELECT  USER_ID,  SUM(AMT) AMTFROM ORDER_INFO OWHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :endGROUP BY USER_IDORDER BY SUM(AMT) DESC

我们得到的是:

SELECT  COUNT(*)FROM (  SELECT    USER_ID  FROM ORDER_INFO O  WHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :end  GROUP BY USER_ID) SQLTOOL

干得漂亮!这完全是我们所期待的。但如果情况再复杂一点呢?比如这样,我们需要查询某段时间内订单金额前一百名的用户:

SELECT  USER_ID, /*用户编号*/  AMT      /*订单金额*/FROM (  SELECT    USER_ID,    SUM(AMT) AMT  FROM ORDER_INFO O  WHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :end  GROUP BY USER_ID) TORDER BY AMT DESCLIMIT 100

我们得到的是:

SELECT  COUNT(*)FROM (  SELECT    USER_ID, /*用户编号*/    AMT      /*订单金额*/  FROM (    SELECT      USER_ID,      SUM(AMT) AMT    FROM ORDER_INFO O    WHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :end  ) T  ORDER BY AMT DESC  LIMIT 100) SQLTOOL

sql-paging没有误杀无辜者,不该去掉的当然要保留原样,这时候仅仅做了必要的包装。

pageSql

用于根据实际查询的SQL生成分页查询SQL,它也不是简单得对源SQL包裹子查询,同样是按需智能决策。继续上述三个例子:

SELECT  S.STAFF_ID,  S.STAFF_NAME,  S.DEPARTMENT_ID,  S.POSITION,  S.STATUSFROM STAFF_INFO SORDER BY S.STAFF_ID

得到的分页查询SQL(以页容量为10,页码第2页为例):

1.1. MySQL

SELECT  S.STAFF_ID,  S.STAFF_NAME,  S.DEPARTMENT_ID,  S.POSITION,  S.STATUSFROM STAFF_INFO SORDER BY S.STAFF_IDLIMIT 10,10

1.2. Oracle

SELECT  STAFF_ID,  STAFF_NAME,  DEPARTMENT_ID,  POSITION,  STATUSFROM (  SELECT    ROWNUM RN__,    SQLTOOL.*  FROM (    SELECT      S.STAFF_ID,      S.STAFF_NAME,      S.DEPARTMENT_ID,      S.POSITION,      S.STATUS    FROM STAFF_INFO S    ORDER BY S.STAFF_ID  ) SQLTOOL  WHERE RN__ <= 20)WHERE RN__ > 10

1.3. PostgresSQL

SELECT  S.STAFF_ID,  S.STAFF_NAME,  S.DEPARTMENT_ID,  S.POSITION,  S.STATUSFROM STAFF_INFO SORDER BY S.STAFF_IDLIMIT 10 OFFSET 10
SELECT  USER_ID,  SUM(AMT) AMTFROM ORDER_INFO OWHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :endGROUP BY USER_IDORDER BY SUM(AMT) DESC

得到的分页查询SQL(以页容量为10,页码第2页为例):

2.1. MySQL:

SELECT  USER_ID,  SUM(AMT) AMTFROM ORDER_INFO OWHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :endGROUP BY USER_IDORDER BY SUM(AMT) DESCLIMIT 10,10

2.2. Oracle

SELECT  USER_ID,  AMTFROM (  SELECT    ROWNUM RN__,    SQLTOOL.*  FROM (    SELECT      USER_ID,      SUM(AMT) AMT    FROM ORDER_INFO O    WHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :end    GROUP BY USER_ID    ORDER BY SUM(AMT) DESC  ) SQLTOOL  WHERE RN__ <= 20)WHERE RN__ > 10

2.3. PostgresSQL

SELECT  USER_ID,  SUM(AMT) AMTFROM ORDER_INFO OWHERE O.CREATE_TIME >= :begin AND O.CREATE_TIME < :endGROUP BY USER_IDORDER BY SUM(AMT) DESCLIMIT 10 OFFSET 10

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request

相关链接

DSL开源地址:https://gitee.com/tenmg/dsl


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap