V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Braisdom
V2EX  ›  Java

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

  Braisdom ·
braisdom · 2020-11-21 23:19:37 +08:00 · 24863 次点击
这是一个创建于 1492 天前的主题,其中的信息可能已经有所发展或是发生改变。

写了 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

  • Dynamic code generation with JSR 269 for Java API of database access
  • Full Java API of database access without coding
  • Dynamically SQL programming with Java syntax, and very close to SQL syntax
163 条回复    2021-02-20 11:03:19 +08:00
1  2  
Braisdom
    1
Braisdom  
OP
   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
    2
Braisdom  
OP
   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
    3
1194129822  
   2020-11-21 23:44:58 +08:00
mark, 好像 mybatis 也有动态构建 SQL 语句的类。SQL 表达力并不强,要不是微软也不用一直扩展 SQL 语法了。java 就是 java,SQL 就是 SQL 。没有银弹。
Braisdom
    4
Braisdom  
OP
   2020-11-21 23:50:56 +08:00
@1194129822 是的,我对比过它的 DynamicSQLBuilder,它做的太土了,大都数都是以字符串的形式体现,我的改进有三块:
1 )动态代码生成:模型中的所有字段都会被动态生成一个 Order 的内部类 Table 中的字段。
2 )算术运算、比较运算符和逻辑运算重载,也就是说 Java 中的 +, -, * / , >, <, &&, || 都会转换成 SQL 语句中的表达式,
3 )我封装了常用数据库的常用函数,例如:count, sum 等有上千个的,这样就不会出现字符

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

但是我选择 Python + SQLAlchemy
beyondex
    17
beyondex  
   2020-11-22 01:06:54 +08:00 via Android
Java 做到这样很棒了,可以了解下 .NET Linq Queryable,语言级支持类似 sql 这样的写法,可以解析后生成 sql 。
EntityFramework 还有 从 Java 移植过来的 NHibernate 都有对这个 Linq Queryable 的实现,十分优雅。
houzhen
    18
houzhen  
   2020-11-22 01:25:51 +08:00   ❤️ 3
夸一下九牛逼就这么难么,太屌了老哥。代表漯河人民支持你。
fiveelementgid
    19
fiveelementgid  
   2020-11-22 01:26:57 +08:00 via Android
C#路过,Linq 玩家用 Entity Framework Core 表示眼熟
LancerComet
    20
LancerComet  
   2020-11-22 01:29:11 +08:00
挺好的,感觉 LinqSql 这个名字更贴切
vone
    21
vone  
   2020-11-22 01:33:41 +08:00   ❤️ 3
@liuhan907
@chinvo
很明显楼主没接触过 .NET 生态。Entity Framework 很多年前就做到了楼主想做的,不仅提供更像 SQL 的 C# ,同时也提供的一套更像 C# 的 SQL 。

假设目标 SQL 为:
SELECT TOP 10 OrderID, Freight FROM Orders ORDER BY Freight DESC


在 .NET (C#) 中使用兰姆达表达式的写法:
Orders.OrderByDescending (m => m.Freight).Select (m =>new{OrderID = m.OrderID,Freight = m.Freight}).Take (10)

在 .NET (C#) 中 LINQ (类 SQL )的写法:
(from m in Orders orderby m.Freight descending select new { m.OrderID,m.Freight }).Take(10)

详细文档:
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/basic-linq-query-operations
pagepancn
    22
pagepancn  
   2020-11-22 01:36:38 +08:00   ❤️ 1
为你的执行力和技术能力点赞,但是真的用处不大。程序员思维啊,缺乏商业眼光
laminux29
    23
laminux29  
   2020-11-22 02:18:27 +08:00   ❤️ 3
1.题主的精神还是值得赞扬的,开源就是需要这种精神,不然开源界完蛋了。

2.做开源有两个麻烦的地方,第一是花了几年功夫辛辛苦苦实现了某个功能,结果官方或别的组织更新一下出了更好的组件,这就尴尬了。第二是写之前没有去做大量的调研,没注意到市面上已经有了更好的实现,比如各大语言的 lambda 表达式。
msg7086
    24
msg7086  
   2020-11-22 03:55:05 +08:00 via Android
表现力是硬伤。用惯 Ruby 的表示这些用 DSL 写写真是小菜一碟……Java 的话可能会难不少。
kingfalse
    25
kingfalse  
   2020-11-22 04:24:49 +08:00
不喜欢 Lombok,更不喜欢再多装一个同类的,好奇两个会不会冲突什么的
justin2018
    26
justin2018  
   2020-11-22 08:32:20 +08:00
以为是 iOS 的 Objective-C
Braisdom
    27
Braisdom  
OP
   2020-11-22 09:28:50 +08:00
@vone 兄弟我还真看过,Entity Framework 针对 比较运算符和逻辑运算符是无法支持的,例如

SELECT * FROM Orders WHERE OrderID > 10 AND Freight = 1

这类写起来太复杂了。

在 ObjectiveSQL 中,缺很方便。

select.where( order.orderId > 10 && order.freight.eq(1) )
Braisdom
    28
Braisdom  
OP
   2020-11-22 09:29:38 +08:00
@kingfalse 两者不会冲突,Lombok 有人爱,有人恨,很正常的,就像 Java 一样,你可以爱他,也可以恨他。
dick20cm
    29
dick20cm  
   2020-11-22 09:38:02 +08:00
老哥真的牛逼!!
cmlanche
    30
cmlanche  
   2020-11-22 09:43:42 +08:00
@pagepancn 我觉得很好
zhuangzhuang1988
    31
zhuangzhuang1988  
   2020-11-22 09:45:51 +08:00
牛逼.
nannanziyu
    32
nannanziyu  
   2020-11-22 09:49:47 +08:00 via Android   ❤️ 1
@Braisdom
LINQ 里
Orders.Where(x=>x.orderId > 10 && x.freight == 1)
huskar
    33
huskar  
   2020-11-22 10:38:07 +08:00 via Android
我感觉这种特性只有在语言层面支持才有意义,第三方库实现的总归写起来麻烦。。。就像各种语言都有类似这种库,但实际用的多的只有 c#的 linq 。
之前刚学 kotlin 的时候也仿照 linq 写了一个类似的东西,利用 kotlin 的中缀表达式能搞的很像直接写 sql,但写完后自己也从来没用过。。。
Braisdom
    34
Braisdom  
OP
   2020-11-22 10:39:06 +08:00
@nannanziyu 兄弟,那是对已经出来的数据进行过滤,而不是在 SQL 中过滤的,
Braisdom
    35
Braisdom  
OP
   2020-11-22 10:39:55 +08:00
@huskar kotlin 和 Scala 很容易的,语言自身就支持运算符重载的。
nannanziyu
    36
nannanziyu  
   2020-11-22 10:57:03 +08:00 via Android
@Braisdom
你的理解是错误的,你需要再了解一下 linq
renyijiu
    37
renyijiu  
   2020-11-22 11:05:58 +08:00
有实际生产项目使用经验吗?
icew4y
    38
icew4y  
   2020-11-22 11:19:12 +08:00 via iPhone
@Braisdom 楼主很牛,楼上有些嘲讽的,估计都是调包侠
levon
    39
levon  
   2020-11-22 11:25:53 +08:00
@Braisdom 并不是对已经读出来的数据过滤,这些最后都会生成对应的 sql 语句的
uselessVisitor
    40
uselessVisitor  
   2020-11-22 11:26:51 +08:00 via Android
支持
Braisdom
    41
Braisdom  
OP
   2020-11-22 11:39:19 +08:00
@renyijiu 现在有 4,5 个公司在用,毕竟刚刚发布 2 个月左右,问题肯定比较多,我也会及时修复的。
avalon8
    42
avalon8  
   2020-11-22 11:42:18 +08:00 via Android
为老哥点个赞,牛逼
Braisdom
    43
Braisdom  
OP
   2020-11-22 11:46:53 +08:00
社区的建设也在准备中,希望更多兄弟参与进来,后面我也将内部的技术原理整理并分享出来。里面的骚操作比较多,不是很常用,缺很实用。
mzlgx
    44
mzlgx  
   2020-11-22 11:47:15 +08:00 via Android
有点意思
fafa2npu
    45
fafa2npu  
   2020-11-22 11:53:20 +08:00 via Android
@Braisdom 首先题主真的很牛逼。但是,querable 的 LINQ 确实是在 SQL 中过滤的,EF 中有个 lazy load,只有在 ToList()等需要取数据的时候才会真正在数据库端执行查询语句。
fafa2npu
    46
fafa2npu  
   2020-11-22 11:55:11 +08:00 via Android
给老哥点个赞
Braisdom
    47
Braisdom  
OP
   2020-11-22 11:58:30 +08:00
@fafa2npu 我仔细研究一下 LINQ,要看最终执行的 SQL 是什么,可以参考一与它的实现原理。其实动态 SQL 只是其中一部分特性
running17
    48
running17  
   2020-11-22 11:59:50 +08:00
点赞,牛逼
abcbuzhiming
    49
abcbuzhiming  
   2020-11-22 12:00:01 +08:00
感觉有点像 Linq,但是我要说的是,这条路已经有人试验过了,不太合适——所有像 SQL 的,为啥不直接用 SQL ?这就是问题的根源,SQL 虽然表达能力一般,但是生命力很强,强到像它的都没熬过它
Braisdom
    50
Braisdom  
OP
   2020-11-22 12:04:41 +08:00
@abcbuzhiming 我要解决的问题如下:
1 )重用性,一个复杂查询中经常会多次 JOIN 同一张表,只有少量变化,SQL 无法解决,只通过通过过程化编程语言解决,Java 只是一种选择而已。
2 )动态性,一个复杂查询中会根据参数不一样,JOIN 不同的表 /子查询,投影不同的字段,当然 Where 后的表达式会有较大的变化。
3 )单元测试,一个复杂 SQL 拆分成多个过程,针对过程进行单元测试,而不是一条非常复杂的 SQL 进行测试
xiangwan
    51
xiangwan  
   2020-11-22 12:07:15 +08:00 via Android
@abcbuzhiming sql 是声明式语言,更先进

@Braisdom jooq 模仿的 linq
Braisdom
    52
Braisdom  
OP
   2020-11-22 12:15:13 +08:00   ❤️ 1
@xiangwan jooq 我参考过,看过它的代码,设计理念很好,但程序设计一般,不够灵活,最关键是的它的代码需要手动生成,每次调整完之后,都得生成一下代码才能编译通过,好麻烦。

SQL 语言设计的初衷是为数据分析人员提供的一种语言,比较接近自然语言,但和逻辑型编译语言结合不是很友好,
目前所有逻辑型编程语言里,都是以字符串的形式存在。

其实回归本质,Java 语言是一门高度抽象的语言,它可以解释一切知识领域,数据库只是一个领域而已,如果没有 SQL 你会怎么设计,怎么样用面向对象的方式设计数据库的访问。

第一性原理,我设计时,先参考现有的知识,然后再忘掉所有的知识,它原本应该怎么样。
Betsy
    53
Betsy  
   2020-11-22 12:19:14 +08:00 via iPhone
印象中 calcite-linq4j 貌似也实现了这样玩法,老哥这个项目跟那个有啥不一样的地方吗?
Braisdom
    54
Braisdom  
OP
   2020-11-22 12:35:27 +08:00
@Betsy Calcite 在我们公司里用了,linq4j 和我的差别很大的,它只是 Java8 Stream 中的扩展,只是对内存中的数据进行过滤和计算,Calcite 本质上是一个关系数据库的计算引擎,做的很不错,后面我也会集成进我的项目,实现异构数据源的计算。
dswyzx
    55
dswyzx  
   2020-11-22 12:50:09 +08:00 via iPhone
我还是喜欢自己掌控 sql 语句,说实在的,通过 linq 去规范以达到运行时报错,或怎么样的好处。在我的狭隘理解里,为何不去掌握好好写 sql 的能力,甚至还可以让公司的 dba 来主动优化这个东西。有人可以辩论一二吗
comsweetcs
    56
comsweetcs  
   2020-11-22 12:53:03 +08:00
首先为楼主的技术点赞。但我真是讨厌 SQL,SQL 调试起来没代码直观,我就是做数据开发的,感觉写代码控制粒度更好,个人觉得后端不可能演变成这种方式,过于死板,不够灵活。
Braisdom
    57
Braisdom  
OP
   2020-11-22 12:54:54 +08:00
@dswyzx DBA 和程序员的职责不一样,面对的问题域也不一样。
DBA:通常面对的是静态问题,考虑的场景也比较单一,用 SQL 作为工具是比较合适,无论是优化,还是维护 SQL 可能是最价的选择,就像脚本型语言是 运维工程师的最爱。

程序员:通过面对的是动态问题,一段含有 SQL 和 Java 的代码逻辑需要满足很多场景,各种奇怪的使用方式,SQL 的构造过程也非常复杂,此时 SQL 语法逻辑和表现力就够用了,如果是纯粹的字符串拼接,也会让程序员崩溃,简单的还好,真复杂起来解决 Bug 的成本 就很高了。
Braisdom
    58
Braisdom  
OP
   2020-11-22 12:57:27 +08:00
@comsweetcs 思考的角度不一样,处理的问题域不一样,对工具的选择就会不同,我们需要更客观的分析
dingyaguang117
    59
dingyaguang117  
   2020-11-22 13:05:10 +08:00
赞 像 sqlalchemy
Pursue9
    60
Pursue9  
   2020-11-22 13:27:41 +08:00
.net 这边已经不写 sql 很多年了,EFcore 已经完全满足操作数据库的需要,生成的 sql 也可以记录在日志里
完全不写 SQL 的 orm 是可行的
Braisdom
    61
Braisdom  
OP
   2020-11-22 13:42:16 +08:00
@Pursue9 认可你的想法,数据分析只是一个问题域,SQL 只是一个协议,我们访问网络时,完全不知道它底层的结构,我们在做 HTTP 应用时,基本也不会接触 HTTP 协议本身,统计和分析数据理论上也应该一样的方式进行演进。
Lemeng
    62
Lemeng  
   2020-11-22 13:46:19 +08:00
赞,学习学习的
beginor
    63
beginor  
   2020-11-22 14:01:50 +08:00 via Android
linq 在 .net 上存在好多年了, 这是不争的事实, 在很多场景下确实比手写 SQL 方便。

在 .net 中有表达式树的概念, 通过分析代码中的表达式树, 动态的转换成 SQL 表达式, 甚至是不同数据库的方言,NHibernate 可以说是典范, 这大概是为什么 NHibernate 仍在活跃开发的原因吧。

当年, .net 平台上也有 mybatis.net , 但是基于 linq 的查询流行之后, 这种手写 SQL 的半自动框架就逐渐没落了。

当然, 完全不写 SQL 也是不可能的, 毕竟 SQL 是基础, 很多复杂的查询也用 SQL 来实现最高效。

凡是都有个二八原则, 不必求全责备。
fangcan
    64
fangcan  
   2020-11-22 14:06:03 +08:00
牛皮 点赞
Braisdom
    65
Braisdom  
OP
   2020-11-22 14:08:51 +08:00   ❤️ 2
@beginor 是的,SQL 历史已经很长,新型技术完全替代,可能需要很长的时间,甚至需要的是一代人。
我们的脑子里要有两个世界,一个是客观存在的世界,一个是我们主观认为的一种世界(也就是世界应该怎么样)。

有时主观认为的世界里有一些正确的事情,客观世界里不一定接受,随着技术的进步,有可能被超越,也有可能在若干后成为主流。
beginor
    66
beginor  
   2020-11-22 15:57:05 +08:00 via Android
这个也可以参考一下,https://github.com/my2iu/Jinq
Braisdom
    67
Braisdom  
OP
   2020-11-22 16:08:49 +08:00
@beginor Jinq 和 ObjectiveSQL 有点类似,但还是有本质的区别,
1 ) Jinq 的表达式依然是 Java 基础表达式形式,也就是只能按 Java 规范进行表达式计算,但在 SQL 中通常会遇到函数调用后的表达式计算
2 ) Select 和 Where 是通过 lambda 解析实现,代码表现力差太多了
tikazyq
    68
tikazyq  
   2020-11-22 16:26:08 +08:00
这是要跟 Entity Framework 一较高下么
zhangysh1995
    69
zhangysh1995  
   2020-11-22 16:36:40 +08:00
点了,支持一下!
Cbdy
    70
Cbdy  
   2020-11-22 16:46:06 +08:00 via Android
很厉害。
说说我的看法,你的目的是类型安全(基于 Java 的类型系统),你尝试达到这个目的的方法是设计一个基于 Java 的 DSL 。
但是(我要泼一下冷水),SQL 就是 SQL,你的 SQL 生成器再精妙,还是不如直接写 SQL 来得简洁有力。
我就不喜欢什么 Linq 、JOOQ,这些东西都是脱裤子放屁,千方百计要用代码去生成 SQL 语句,而不是直接写 SQL 。
一方面,写 SQL 是必要的工作,最终调优的时候、Troubleshooting 的时候还不是要去看 SQL ?类型不安全的 SQL 往往在写代码的时候就会发现,这个问题也不是写 SQL 面临的主要矛盾。更多的,SQL 也是一门久经考验的“语言”,也有丰富的静态检查工具。
我支持 SQL 。
Braisdom
    71
Braisdom  
OP
   2020-11-22 16:53:52 +08:00
@Cbdy 其实很多人都有你这样的想法,我前期遇到很多这样的想法来挑战 ObjectiveSQL,喜欢与不喜欢是很主观的,我也不参与这样的争论,就像争论哪种编程语言好一样

我们需要更客观一点看,有的公司 SQL 多,有的公司 SQL 少,有的复杂,有的相对简单,这样的背景下在选择工具时就会有不同的想法。

我是经历过一个项目中存在 500 - 1000 条长度超过 400 行的 SQL,平均每个 SQL 需要 JOIN 20 张表或子查询(有较多重复),在这样的场景下 SQL 的维护成本,修复 Bug 的成本,单元测试的成本是巨大的。

这些经历导致了我的项目的出现,当然 @Cbdy 你可能有不一样的背景。
Cbdy
    72
Cbdy  
   2020-11-22 17:07:08 +08:00 via Android
@Braisdom 确实可能存在你说的情况,那种情况无论用什么工具都是很复杂的,因为数据存成这样,已经有一个复杂度在了。我觉得要控制这个复杂度的话,应该从数据角度出发。

这种场景基本是 OLAP 或者出报表吧,如果是这样,可以考虑抽取数据到宽表,或者更灵活的非关系存储
uptonking
    73
uptonking  
   2020-11-22 17:07:52 +08:00 via iPhone
虽然有很多质疑,我还是觉得楼主很厉害,开源就是要经得起检验,,,可以参考下大家提到的优秀方案,然后吸收一部分到 objectiveSQL,把 README 或项目主页写详细点
Braisdom
    74
Braisdom  
OP
   2020-11-22 17:18:11 +08:00
@Cbdy 很多应用都会有报表的,只是多少的问题,Java 的代码可以成千上万行,有语法层结构化的形式进行管理,同样也存在很多模式和规范,这块在 SQL 上就很少了,SQL 的工程化能力远远不如 Java 。

所以通过 Java 的形式去写 SQL 是很必要的,但 SQL 已经诞生了很多年,而且被很多人所接受,如果设计一套全新的语法模式,大众很难接受,这样项目的生命力也不强,所以我尽可能的让 Java 代码接近 SQL,符合大众的味口,哈哈。

“Dynamically SQL programming with Java syntax, and very close to SQL syntax”

我之前设计过一个语言,我称它为 JDS(Java Database Script) 后来放弃了,在我的 github 也有。
Braisdom
    75
Braisdom  
OP
   2020-11-22 17:27:09 +08:00
@uptonking 是的,只有经得起大家挑战的项目才有生命力,总是靠人扶肯定长不大的。
Cbdy
    76
Cbdy  
   2020-11-22 17:28:47 +08:00 via Android
@Braisdom Java 是通用语言,SQL 是领域特定语言,把 Java 和 SQL 进行比较还是蛮怪的。如果要说他们之间的关系,SQL 可以成为 Java 能力的延伸,本身和 Java 不矛盾。试图用 Java 解决所有问题才是比较奇怪的做法。况且很多数据库都有专有的语法,函数库,用的时候隔着一层“通用”的封装,可能会很鸡肋。
mumubin
    77
mumubin  
   2020-11-22 17:29:55 +08:00
自己做出来这个工具,老哥还是很值得肯定的。不过作为程序员我还是喜欢直接写 sql,及其讨厌非 sql 的 orm 。所以我还是最喜欢 mybatis 。维护一个 django 项目,自带 orm 中的坑点不少,而且 slow sql 都挺难定位的。
Braisdom
    78
Braisdom  
OP
   2020-11-22 17:35:51 +08:00   ❤️ 1
@Cbdy 要从不同的角度去理解 SQL,SQL 其实和 HTTP,SMTP 这类协议一样,只不过 SQL 是解决 Java 与数据库交互的一种协议,我相信你不会手动编码去实现 HTTP,SMTP 这类协议的,都是通过更高层的封装去访问,当然如果做更底的编码,还是会涉及的。
Braisdom
    79
Braisdom  
OP
   2020-11-22 17:37:05 +08:00
@mumubin 很多人都有你这样的想法,slow sql 也是我下一阶段需要解决的,如果通过单元测试排查一部分常见的问题。
Cbdy
    80
Cbdy  
   2020-11-22 17:49:12 +08:00 via Android   ❤️ 1
@Braisdom SQL 是 Query DSL,HTTP 这种事 Application layer communication protocol,他们的复杂度、拓展性、和解决的问题是不同的,怎么能混为一谈
heiheidewo
    81
heiheidewo  
   2020-11-22 17:50:56 +08:00
牛逼,长见识了
felixcode
    82
felixcode  
   2020-11-22 17:55:22 +08:00 via Android
如果要针对数据库做 sql 优化能做吗?
Braisdom
    83
Braisdom  
OP
   2020-11-22 17:57:21 +08:00
@Cbdy 你说的很对,SQL 的复杂度相比其它是高出很多,但从抽象的角度去看,它就是一种协议,只不过这种协议承载了较多关系型数据的计算逻辑和统计方式而已。

我只是做了一个类比,传输层协议更多是定义结构,其内存的逻辑更多是由程序控制的。

数据库设计的初衷就是为了封装数据的计算逻辑,降低外部应用程序的复杂度,提供简单的交互协议实现数据计算,但随着数据统计方式的发展,问题领域的复杂度变化,传统的方式编写 SQL 已经很难满足分析需求了,只就需要逻辑型编程语言提供封装,隐藏复杂的构造过程。
Braisdom
    84
Braisdom  
OP
   2020-11-22 18:00:32 +08:00
@felixcode 你说的其实一个 SQL 性能测试引擎,完全做到很难,毕竟场景太复杂,但随着不断的迭代,能够避免大量 SQL 的错误,这是我下一阶段工作的重点。
vipcc
    85
vipcc  
   2020-11-22 18:05:07 +08:00 via Android
.net core 中的 ef core +linq,老哥可以看一看
现在都是开源的
Braisdom
    86
Braisdom  
OP
   2020-11-22 18:06:17 +08:00
@vipcc 感谢,我会参考一下,前面已经有好几位兄弟介绍了。
felixcode
    87
felixcode  
   2020-11-22 18:06:23 +08:00 via Android
你做的东西可能比较有用,但你对 SQL 语言的理解局限性太大了。

结合 dbms 的具体实现,sql 从顶层的描述到底层的控制都是能做的,你做一层翻译后,牺牲了 sql 语言的很多特性。
Cbdy
    88
Cbdy  
   2020-11-22 18:20:42 +08:00 via Android
传统的方式编写 SQL 已经很难满足分析需求了,只就需要逻辑型编程语言提供封装,隐藏复杂的构造过程

难道不是 data flow 、data structure 设计有问题吗?😂
beginor
    89
beginor  
   2020-11-22 18:26:40 +08:00 via Android   ❤️ 1
楼主的这个项目非常有意义,Java 确实没有强大的,广为人知并且深入人心的类似于 Linq2SQL 的 ORM 框架, 但是 Linq2SQL 的功能在 .Net 平台上已经深入人心, 被绝大多数人所接受。

在 .Net 平台的刚刚开始出现 Linq2SQL 的功能的时候, 很多人也是类似的泼冷水。 但是 Linq2SQL 确实成功的提升了许多 .Net 开发者的生产力。

我是做 .Net 出身, 最近几年也接触过一些 Java 的项目, 两个平台都了解一些, 也可以说是深有感触。

不过这种项目最好有大公司参与推广, 单纯个人推广会很难。
optional
    90
optional  
   2020-11-22 19:21:43 +08:00 via iPhone
隔壁有个 ktorm,虽然不是 java 但是可以一起用的
hangs
    91
hangs  
   2020-11-22 20:15:55 +08:00
@Braisdom 请教两点

1. 插件是必须装的吗,还是引入对应的 maven 依赖即可。

2. 在简单 ORM 不涉及复杂计算的情况下,mybatis 、hibernate 和您这个框架优劣势分别是哪些呢
Tlin
    92
Tlin  
   2020-11-22 20:19:19 +08:00
这些都是什么人啊 那么厉害吗
看来我不敢发言了………………

真厉害啊!👍👍👍👍👍
怎么看老哥像技术胖呢
xrr2016
    93
xrr2016  
   2020-11-22 21:06:30 +08:00
看起来像一种 ORM,类似于 https://www.prisma.io 这个吗?
WhoMercy
    94
WhoMercy  
   2020-11-22 21:13:10 +08:00
感谢、收藏。

下次做练手项目再来试试老哥这个框架。
bojue
    95
bojue  
   2020-11-22 21:14:27 +08:00
@Tlin 你不是一个人,技术胖没这个实力
Braisdom
    96
Braisdom  
OP
   2020-11-22 21:26:51 +08:00
@beginor 非常认可你的说法,没有大公司的背书,项目很难起来。
Braisdom
    97
Braisdom  
OP
   2020-11-22 21:28:33 +08:00
@hangs 兄弟,插件是必须的,由于 IntelliJ IDEA 的 Java 语法检测太严谨,我已经提了 issue 给他们了,说是会有改进,我是自动生成 java 代码,没有 IDE 的支持很难完成。
Braisdom
    98
Braisdom  
OP
   2020-11-22 21:30:14 +08:00
@Cbdy 问题领域的复杂度是无法避免的,所以需要通过 Java 去避免复杂度的蔓延
Braisdom
    99
Braisdom  
OP
   2020-11-22 21:43:34 +08:00
@hangs 如果不涉及复杂 SQL,你可参考一下我 git 文档里的描述,自动代码生成相比其它 ORM,优势自已体会一下,我说再说也不没有说服力。
Braisdom
    100
Braisdom  
OP
   2020-11-22 21:48:32 +08:00
@zhangysh1995 感谢支持
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   883 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 32ms · UTC 19:57 · PVG 03:57 · LAX 11:57 · JFK 14:57
Developed with CodeLauncher
♥ Do have faith in what you're doing.