历经 3 年,终于得以实现了

2020-11-21 23:19:37 +08:00
 Braisdom

写了 15 年的程序,人到中年总有很多话要说,千言万语尽在项目里,里面有我想说的一切。

项目地址: https://github.com/braisdom/ObjectiveSql

ObjectiveSQL 是我构想了很长时间,到底是让 Java 像 SQL 一样编程,还是让 SQL 让 Java 一样编程,纠结了很久,还是让 Java 更像 SQL,Java 的语法表现力不够,只能扩展 Javac,实现了算法运算,比较运算,逻辑运算符重载,并封装了常用数据的的函数,抽象了 Expression,使的 Java 非常接的 SQL,同时也实现了简单 SQL 编程的代码生成,基本不需要写代码,也不需要配置就能实现简单 SQL 的编程,话不多说,先看示例,有兴趣可以到 github 上看。

Order.Table orderTable = Order.asTable();
Select select = new Select();

select.project(sum(orderTable.amount) / sum(orderTable.quantity) * 100)
    .from(orderTable)
    .groupBy(orderTable.productId);
Member.Table member = Member.asTable();
Order.Table order = Order.asTable();

Select select = new Select();

select.from(order, member)
        .where(order.memberId.eq(member.id));
select.project(member.no,
        member.name,
        member.mobile,
        countDistinct(order.no).as("order_count"),
        sum(order.quantity).as("total_quantity"),
        sum(order.amount).as("total_amount"),
        min(order.salesAt).as("first_shopping"),
        max(order.salesAt).as("last_shopping"));
select.groupBy(member.no, member.name, member.mobile);

ObjectiveSQL is an ORM framework in Java base on ActiveRecord pattern, which encourages rapid development and clean, codes with the least, and convention over configuration.

Features

24856 次点击
所在节点    Java
163 条回复
Braisdom
2020-11-21 23:35:02 +08:00
补充一下,第一段 Java 代码生成的 SQL 如下:
```sql
SELECT
((((SUM(`T0`.`amount` ) / SUM(`T0`.`quantity` ) )) * 100))
FROM
`orders` AS `T0`
GROUP BY
`T0`.`product_id`
```
Braisdom
2020-11-21 23:36:30 +08:00
第二段 Java 代码生成的 SQL 如下:
SELECT
`T0`.`no` ,
`T0`.`name` ,
`T0`.`mobile` ,
COUNT(DISTINCT `T1`.`no` ) AS `order_count`,
SUM(`T1`.`quantity` ) AS `total_quantity`,
SUM(`T1`.`amount` ) AS `total_amount`,
MIN(`T1`.`sales_at` ) AS `first_shopping`,
MAX(`T1`.`sales_at` ) AS `last_shopping`
FROM
`orders` AS `T1`,
`members` AS `T0`
WHERE
(`T1`.`member_id` = `T0`.`id` )
GROUP BY
`T0`.`no` ,
`T0`.`name` ,
`T0`.`mobile`
1194129822
2020-11-21 23:44:58 +08:00
mark, 好像 mybatis 也有动态构建 SQL 语句的类。SQL 表达力并不强,要不是微软也不用一直扩展 SQL 语法了。java 就是 java,SQL 就是 SQL 。没有银弹。
Braisdom
2020-11-21 23:50:56 +08:00
@1194129822 是的,我对比过它的 DynamicSQLBuilder,它做的太土了,大都数都是以字符串的形式体现,我的改进有三块:
1 )动态代码生成:模型中的所有字段都会被动态生成一个 Order 的内部类 Table 中的字段。
2 )算术运算、比较运算符和逻辑运算重载,也就是说 Java 中的 +, -, * / , >, <, &&, || 都会转换成 SQL 语句中的表达式,
3 )我封装了常用数据库的常用函数,例如:count, sum 等有上千个的,这样就不会出现字符

上述做法的好处是,最大程度的避免的 SQL 的语法错误,动态代码提示和单元测试。
VHacker1989
2020-11-21 23:57:04 +08:00
querydsl mybatisplus 都有更好的实现,用面向对象语言实现蹩脚的 dsl 风格 api 简直多余,还不如简单查询 jpa,复杂查询 sql 高低搭配
Braisdom
2020-11-22 00:06:10 +08:00
@VHacker1989
1 )首先我做这个项目前肯定是看过 JOOQ, QueryDSL 这类项目的,它有致命缺点就是 Java 的表达式无法 SQL 表达式重合,这会导致所谓的 SQL Builder 在复杂 SQL 中根本无法使用,我项目里有个计算同环比的简单示例,有大量的数运算和逻辑运算,如果运算符通过函数的形式实现,那样的代码根本无法看。
2 )我的项目中参考了 Lombok 的动态代码生成,能够减少绝大部分的重复代码,它们是无法做的。
Braisdom
2020-11-22 00:07:57 +08:00
@VHacker1989 像这样的代码:“ sum(orderTable.amount) / sum(orderTable.quantity) * 100”
你猜 MyBatis, JOOQ, QueryDSL 会写成什么样?
Braisdom
2020-11-22 00:09:25 +08:00
一门语言,它的语法表现边非常重要,能够准确的描述出业务领域的关键特征,是一段代码可维护性的重要标志
u6pM63mMZ34z32cE
2020-11-22 00:17:59 +08:00
knex.js
shade
2020-11-22 00:22:05 +08:00
跟 APIJSON 比较,有什么优势呢?
liuhan907
2020-11-22 00:22:53 +08:00
这看起来好像山寨版的 entity framework 啊。这个仅限查询么,是否支持自动 diff 和修改?
Braisdom
2020-11-22 00:28:37 +08:00
@liuhan907 什么叫山寨版,相比现有的 ORM 框架,优势主要体现在:
1 )动态代码生成,类似 Lombok
2 ) Java 运算符重载,领先于现有的所有 ORM 框架
3 )函数封装是参考 JOOQ 的
Braisdom
2020-11-22 00:29:00 +08:00
@shade apijson 好像不是同一类东西
chinvo
2020-11-22 00:33:25 +08:00
@Braisdom #12 你真的需要去了解下 LinQ 和 Entity Framework,开阔下眼界
AlexaZhou
2020-11-22 00:53:59 +08:00
看用法比 mybatis 方便多了,支持一个
oahebky
2020-11-22 00:57:44 +08:00
很厉害,我做不出来;

但是我选择 Python + SQLAlchemy
beyondex
2020-11-22 01:06:54 +08:00
Java 做到这样很棒了,可以了解下 .NET Linq Queryable,语言级支持类似 sql 这样的写法,可以解析后生成 sql 。
EntityFramework 还有 从 Java 移植过来的 NHibernate 都有对这个 Linq Queryable 的实现,十分优雅。
houzhen
2020-11-22 01:25:51 +08:00
夸一下九牛逼就这么难么,太屌了老哥。代表漯河人民支持你。
fiveelementgid
2020-11-22 01:26:57 +08:00
C#路过,Linq 玩家用 Entity Framework Core 表示眼熟
LancerComet
2020-11-22 01:29:11 +08:00
挺好的,感觉 LinqSql 这个名字更贴切

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/727939

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX