常有人问起, SqlDdlDao 工具类对于 sql 规范的支持版本和支持程度.
因此, 在这里对 sql 规范的支持版本和程度做一下简单的归纳.
目前主要实现的是 sql 规范的 DQL 部分, 因此主要实现的是 SqlDqlDao 部分.
| 需求 | 对应接口 | 说明 | jdbc完成度 | java完成度 |
|---|---|---|---|---|
| DQL | SqlDqlDao SqlDqlStreamDao |
负责数据查询, 主要是: select | 80% | 100% |
| DML | SqlDmlDao | 负责数据修改, 主要是: insert, update, delete | 0% | 90% |
| DDL | SqlDdlDao SqlDdlStreamDao |
负责表结构管理, 比如: create table / index 继承前两个接口 |
0% | 20% |
| DCL | 无 | 事务等管理 | 0% | 0% |
下面是SQL发展的简要历史:
* 1986年,ANSI X3.135-1986,ISO/IEC 9075:1986,SQL-86
* 1989年,ANSI X3.135-1989,ISO/IEC 9075:1989,SQL-89
* 1992年,ANSI X3.135-1992,ISO/IEC 9075:1992,SQL-92(SQL2)
* 1999年,ISO/IEC 9075:1999,SQL:1999(SQL3)
* 2003年,ISO/IEC 9075:2003,SQL:2003
* 2008年,ISO/IEC 9075:2008,SQL:2008
* 2011年,ISO/IEC 9075:2011,SQL:2011
其中比较重要的标准是 SQL-92, 因此本文主要讨论 SqlDdlDao 对于 SQL-92 版标准内容的支持程度.
参考链接: https://blog.csdn.net/BeiiGang/article/details/43194453
SqlDdlDao 目前只是一个查询工具, 因此基于SQL语句的增删改基本上都没有实现.
修改数据的能力由 common 开放的 java 方法实现.
[ WITH tableName1 AS ( query ), tableName2 AS ( query ), ... ]
SELECT [ DISTINCT ] { * | exprs }
FROM { table | ( query ) }
[ WHERE expr ]
[ GROUP BY exprs ]
[ HAVING expr ]
[ ORDER BY expr [ ASC | DESC ], expr [ ASC | DESC ], ... ]
[ SKIP skip]
[ LIMIT [ skip, ] limit ]
[ UNION [ ALL ] <another query> ]
| 查询语句 | 支持程度 |
|---|---|
| USE | 支持 |
| SHOW DATABASES [LIKE ‘%aa%’] | 支持 |
| SHOW TABLES [FROM DB_NAME] [LIKE ‘%aa%’] | 支持, 允许跨数据源 |
| SHOW TABLE STATUS [FROM DB_NAME] [LIKE ‘%aa%’] | 支持 |
| SHOW CREATE TABLE | 支持 (nosql数据库使用第一行模拟) |
| SHOW COLUMNS FROM / DESCRIBE / DESC | 支持 (nosql数据库使用第一行模拟) |
| SHOW [FULL] PROCESSLIST | 支持 (模拟) |
| SHOW FUNCTIONS | 支持 (模拟) |
| SET @a := 1 | 支持 |
| UNION / UNION ALL | 支持, 允许跨数据源 |
| SELECT DISTINCT | 支持 |
| CASE WHEN THEN ELSE END | 支持 |
| FROM table / FROM (select …) | 支持 |
| FROM table1 a, table2 b | 非 jdbc 数据源: 不支持 jdbc 数据源: 直接转发给数据库 |
| WHERE a in (select …) | 支持, 允许跨数据源 |
| GROUP BY | 支持 |
| HAVING a in (select …) | 支持, 允许跨数据源 |
| ORDER BY | 支持 |
| SKIP / LIMIT | 支持 |
| [INNER / LEFT / RIGHT / FULL] JOIN | 非标准语法支持, 允许跨数据源 |
| ON / USING | 支持 |
| 数据类型 | 支持程度 |
|---|---|
| BOOLEAN | 支持 |
| CHAR(n) / CHARACTER(n) | 支持 |
| VARCHAR(n) / VARCHAR2(n) | 支持 |
| CHARACTER VARYING(n) | 支持 |
| INTEGER / INT / SMALLINT | 支持 |
| DECIMAL(p,s) / DEC(p,s) / NUMERIC(p,s) / FLOAT(p) / REAL | 支持 |
| DOUBLE PRECISION | 支持 |
| DATE / datetime / timestamp | 支持 |
| TIME | 未评估 |
| INTERVAL year-month / day | 未评估 |
| BLOB | 不支持 |
| 条件 | 支持程度 |
|---|---|
| < > <= >= <> = | 支持 |
| AND OR NOT | 支持 |
| IS [NOT] NULL | 支持 |
| [NOT] LIKE | 支持 |
| [NOT] IN ( [,…] ) | 支持 |
| [NOT] BETWEEN x AND y | 支持 |
| [CONDITIONAL] ANY ( [,…] ) | 不支持 |
| [CONDITIONAL] ALL ( [,…] ) | 不支持 |
| ‘abc’ [NOT] REGEXP ‘^a.*’ | 支持 |
| ‘abc’ [NOT] RLIKE ‘^a.*’ | 支持 |
| 函数 | 支持程度 |
|---|---|
| AVG / MAX / MIN / SUM / COUNT | 支持 |
| GREATEST / LEAST(x,y,…) | 支持 |
| ROUND | 支持 |
| TRUNC(x,places/date,format) | 不支持 |
| POSITION(s1 IN s2) | 不支持 |
| EXTRACT(datetime FROM datetime_value) | 支持 |
| CHAR_LENGTH(s1) / LENGTH(s1) | 支持 |
| SUBSTRING(string FROM start [FOR length]) / SUBSTR(string,start,length) | 部分支持 |
| INSTR(str,substr,start,mnth) | 不支持 |
| INITCAP | 支持 |
| UPPER / LOWER(string) | 支持 |
| TRIM(BOTH/LEADING/TRAILING char FROM string) | 支持 |
| [L/R]TRIM(str,chrset) | 支持 |
| TRANSLATE / CONVERT(char USING value) / TRANSLATE(str,from,to) | 部分支持 |
| [L/R]PAD(str,to_len,str2) | 支持 |
| DECODE(expr,search1,result1,…[,default]) | 不支持 |
| NVL(expr,replace) | 支持 |
| Date Format - ROUND / TRUNC / TO_CHAR / TO_DATE(value,fmt) | 部分支持 |
| IF / IFNULL / COALESCE | 支持 |
| row_number() OVER ([partition by b] [order by a]) | 支持 |
| lag() OVER ([partition by b] [order by a]) | 支持 |
参考链接: https://blog.csdn.net/zhongmengya/article/details/5049025
像 now(), curdate(), FIND_IN_SET() 等函数, 未被此版规范提及, 因此上表未有列出.
可以使用 show functions 查询所有支持使用的非聚合函数.
set @a = 1+1;
set @a = (select count(1) from t);
select @a:=@a+1;
可以用以下链接尝测试执行sql, 其中的 sql 及 json数据 可以随意替换. 也可以使用测试表: sql_demo_table,mongo_demo_table,cinema_info
HBaseDaoImpl 是 SqlDdlDao 接口的 hbase 实现类, 实现了基于sql的各种数据查询能力.
为了方便查询离线文件, 准备了 dw-util-select-file.jar.
支持查询本地多个 csv, json, xls, xlsx 文件中的数据,支持联合查询
语法: java -jar dw-util-select-xls.jar [--out=输出路径] 'sql' '数据文件路径1' ['数据文件路径2' ...]
sql 此伪sql支持多表嵌套嵌套查询,少部分语法与mysql不一致
文件路径 可以为多个 csv, json, xls, xlsx 文件, 第一个xls会映射为'data_1'表,第二个为'data_2'...所有xls的数据会映射为'data_all'表
java -jar dw-util-select-xls.jar "select type, max(num) as max_num, min(num) as min_num from data_all where type != 'A' group by type order by type" 'd:/num_1.xlsx' 'd:/num2.xlsx'
java -jar dw-util-select-xls.jar "select type, max(num) as max_num, min(num) as min_num from data_1 where type not in (select type from data_2 where id = 2) group by type order by type" 'd:/num_1.xlsx' 'd:/type.xls'
使用sql查询到的数据,可以输出为一个 excel 或者 table。因为sql中无法表达 x轴 y轴 等定义信息, 无法直接输出为 echarts 图表。
为了解决数据可视化问题, 我们准备了 data view 工具。将 sql 的结果直接输出为 echarts 可用的格式, 或者其他需要的数据格式。
to_scope_list 函数是折线图与柱图的 data view 实现。
to_scope_list('t', '20200101~20200131', 'date', 't', 'c', '1DAY', 0)
| 参数 | 限制 | 举例 | 说明 |
|---|---|---|---|
| xField | 必填,唯一 | x | x轴对应的字段 |
| xScope | 可选 | date范围:180101~180201 long范围:1~10 str指定范围:北京,上海,广州 str自适应:null 指定策略, 比如按指定字段降序排列: order by sum(value) desc limit 10 (limit N 与 desc 非必填) |
x轴的范围 |
| xConver | 可选 | 日期用:date 或 to_date() 数字用:long 或, to_long() 字符串用:string |
不区分大小写, x轴转换类 经常遇到x轴的值为String, 但需要int型递增 此参数可以对此做数据转换 |
| aggFields | 必填,不唯一 | plan | 折线的field, 用于控制一行 row 中有几条折线 |
| groupKeys | 必填,不唯一 | x, x1, x2 | 折线的key, 用于生成图例 |
| interval | 可选 | 86400, 1, 1DAY, 1MONTH | x轴的间隔, |
| defaults | 可选 | null 或者 0 | 折线图无值时,数据当什么处理. |
import cn.sybn.bean.result.conver.result.ResultToMapConverPool;
String resultView = "to_scope_list('t', '20190101~20190131', 'to_date()', 't', 'c', '1DAY', 0)"
List<Map<String, Object>> data = dao.sqlFindListMap("select t, count(*) as c from table where t between 20180101 and 20180131 group by t order by t")
ResultBase res = new ResultTRows<>(data);
ResultConver resultConver = ResultToMapConverPool.get(resultView);
ResultBase res2 = resultConver.conver(res);
{
"result" : true,
"msg" : "success",
"total" : 1,
"attachment" : {
"_group_by" : [ ],
"_group_fields" : [ "c" ],
"_group_x_field" : "t",
"_group_y_field" : "'c'",
"_group_scope_interval" : "1DAY",
"_group_scope_list" : [ "2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-05", "2019-01-06", "2019-01-07", "2019-01-08", "2019-01-09", "2019-01-10", "2019-01-11", "2019-01-12", "2019-01-13", "2019-01-14", "2019-01-15", "2019-01-16", "2019-01-17", "2019-01-18", "2019-01-19", "2019-01-20", "2019-01-21", "2019-01-22", "2019-01-23", "2019-01-24", "2019-01-25", "2019-01-26", "2019-01-27", "2019-01-28" ]
},
"rows" : [ {
"_" : null,
"value_scope_start" : "2019-01-01",
"value_scope_end" : "2019-01-28",
"plan" : [ 98832, 89188, 88477, 94331, 98127, 97541, 88971, 91883, 90769, 89554, 101539, 101411, 100595, 91890, 91782, 92129, 91568, 102538, 103876, 103814, 95736, 95367, 95750, 96365, 99826, 102768, 102364, 95084 ],
"ticket" : [ 7454, 2097, 1735, 5957, 7649, 6009, 2353, 2063, 2079, 2012, 3611, 5106, 4042, 2010, 1882, 2137, 2105, 3713, 5120, 4895, 2455, 2133, 2428, 2114, 4300, 4458, 4071, 2494 ],
"sum_plan" : 2692075.0,
"sum_ticket" : 98482.0
} ]
}
前端可以使用 charts.js 直接将上面的 json 结果集渲染为折线图.
如果有美化要求,可以让前端人员修改 charts 风格.
上述内容已经集成进 api-core 接口项目中,
api-core 是业务层通用组件, 本文档主要讲述 dao 层通用组件,因此不专门阐述.
以下是 api-core 效果图, 集成了跨数据库类型查询 ,sql代码提示, 数据可视化三个特性.

2019-04-28 V:0.3.2
支持 string 型x轴, 并支持自适应和动态适配。
部分同学不熟悉 mongodb 的查询语法,为了降低入门门槛,今天专门提供了转换类。
已经为大家准备好了 web 版接口: 在线测试
// params 支持 ? 和 #{name} 占位符
MongoAggregateBuilder.makPipeline(@NonNull String sql, Object... params)
select
(case type when 1 then value1 when 2 then value2 else 0 end) as t,
count(*) as c
from table
where date > str_to_date('2019-04-07', '%Y-%m-%d')
group by t
having c > 10
order by c desc
输出 Aggregate:
[
{"$match":{"date":{"$gt":{"$date":"2019-04-06T16:00:00Z"}}}},
{"$group":{"_id":{"t":{"$cond":{"if":{"$eq":["$type",1]},"then":"$value1","else":{"$cond":{"if":{"$eq":["$type",2]},"then":"$value2","else":0}}}}},"c":{"$sum":1}}},
{"$project":{"_id":0,"t":"$_id.t","c":1}},
{"$match":{"c":{"$gt": 10}}},
{"$sort":{"c":-1}}
]
mongo 只能支持 select 和 from 子查询, 无法支持 where 子查查询 和 join
此工具类暂时不支持加减乘除运算
mongo对数据类型敏感,MySQL 中的 date > str_to_date(‘2019-04-07’, ‘%Y-%m-%d’) 可以写为 date > ‘2019-04-07’ 但 mongo 不可以。

