历经 3 年,终于得以实现了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Braisdom
V2EX    Java

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

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

写了 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 语句的
zm8m93Q1e5otOC69
    40
zm8m93Q1e5otOC69  
   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     Solana     2812 人在线   span class="fade">最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 41ms UTC 00:21 PVG 08:21 LAX 17:21 JFK 20:21
Do have faith in what you're doing.
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86