Java ORM 中简洁的关联对象查询和分页查询

2020-11-28 09:41:51 +08:00
 Braisdom

只需要定义一个 DomainModel

@DomainModel
public class Member {
    private String no;
    
    @Queryable
    private String name;
    private Integer gender;
    private String mobile;
    private String otherInfo;

    @Relation(relationType = RelationType.HAS_MANY)
    private List<Order> orders;
}

关联对象查询方法:

Member.queryAll(Member.HAS_MANY_ORDERS);
Member.queryByPrimary(1, Member.HAS_MANY_ORDERS);
Member.queryByName("demo", Member.HAS_MANY_ORDERS);

分页查询:

Page page = Page.create(0, 10);
PagedList<Member> members = Member.pagedQueryAll(page, Member.HAS_MANY_ORDERS);

更多请参考: https://github.com/braisdom/ObjectiveSql

3529 次点击
所在节点    Java
27 条回复
hantsy
2020-11-28 10:55:27 +08:00
QueryDSL 早实现了。
wysnylc
2020-11-28 11:12:31 +08:00
关联查询存在 N+1 问题
分页查询用 pageHelper
Braisdom
2020-11-28 11:33:32 +08:00
@hantsy 哈哈,我和 QueryDSL 有本质的区别,有必要写个两者的区别,有兴趣看一下

https://github.com/braisdom/ObjectiveSql 文章的最后
Braisdom
2020-11-28 11:34:07 +08:00
@wysnylc N+1 的问题已经解决了。


@hantsy 最关键我是不需要写代码的,哈哈
hantsy
2020-11-28 12:04:52 +08:00
和 JOOQ 呢?
hantsy
2020-11-28 12:05:50 +08:00
JOOQ 和 QueryDSL 都是可以生成方便 DSL 表达的查询语句代码。
hantsy
2020-11-28 12:09:21 +08:00
加一个 @DomainModel 把贫血模型,变成 Rich Model 。这个与以前的 Spring Roo 1.x ( Spring 放弃这个项目)类似。https://github.com/hantsy/spring-sandbox/wiki/tao-of-spring-roo
Braisdom
2020-11-28 12:12:49 +08:00
@hantsy

是的它们两个都可以通过 Java 代码生成 SQL,但他们有致命的缺点。
1 ) Java 代码的生成需要手动编译,这样的话模型内容变化里,需要手动生成代码。
2 )算术运算符、比较运算符和逻辑运算都是通过方法的形式实现,这样会使 Java 代码过于复杂

举个简单的例子:

SQL 表达式:
(`T0`.`quantity` > 30) AND `T0`.`sales_at` BETWEEN '2020-10-10 00:00:00' AND '2020-10-30 23:59:59')

QueryDSL 和 JOOQ 中会是这样的

exp.and(table.quantity.gt(30), table.salesAt.between("2020-10-10 00:00:00", "2020-10-30 23:59:59")

而 ObjectiveSQL 中是这样的:

orderTable.quantity > 30 && orderTable.salesAt.between("2020-10-10 00:00:00", "2020-10-30 23:59:59")

你能看出区别吗?如果表达式再复杂一点呢?
Braisdom
2020-11-28 12:15:42 +08:00
@hantsy
贫血模型 与充血模型 本质上不重要,关键对开发来讲,你的效率有没有得到提升,思考问题要从实际出发。

不需要编写一行额外的代码,就能实现一张表的
1 )简单基于属性的查询
2 )关联对象查询
3 ) Validation
还有更多...
Braisdom
2020-11-28 12:17:34 +08:00
@hantsy 我在设计 ObjectiveSQL 时,已经忘记了 SQL 的存在,站在 Java 语言的基础上思考,如果通过 Java 语言更方便的查询和分析数据,这是本质
liununu
2020-11-28 12:23:47 +08:00
@hantsy 加上 DomainModel 的 Annotation 也没有变成充血模型吧,充血的应该是业务逻辑的方法。如果真把 Annotation 加到 Domain Model 上,其实算是把技术框架的实现入侵到了业务。
Braisdom
2020-11-28 12:31:24 +08:00
@liununu
你说法非常正确,讨论到问题的核心了
大都数业务中,一个 DomainModel 会对应数据库中的一张表,而 DomainModel 也就承担了基础的数据库访问能力,以及围绕该 DomainModel 产生的业务特性。

ObjectiveSQL 只是动态生成了所有数据库访问的能力,不需要额外编写代码就可以直接使用,减少重复的编码量,提升开发效率。

至于上面描述的复杂 SQL 的编程,只是在 DomainModel 中进行复杂的业务逻辑处理时所用的特性。

ObjectiveSQL 和 Spring 一样都是侵入原生的 Java Class,只不过 Spring 更加隐晦,你感觉不到,而 ObjectiveSQL 的侵入更加明显,而且与实际的业务代码进行结合。这就是和 Sping 本质的区别
hantsy
2020-11-28 12:40:42 +08:00
好吧。

都是使用 Java 5 中的 APT 生成代码,要么修改最终的 Class (如,Lombok ),要么和 JPA 一样另外外生成一些 Java 源文件,再编译成 Class 。我不知道你说的要手动生成什么意思,IDEA,Eclipse 只要 Enable Annotatoins Processor 就可以了。如果脱离 IDE,使用 Maven 都要编译处理。NetBeans 天生支持 Annotation Processor,会自动检测变化。

如果站在 Java 的角度思考,我会尽量 OOP 思维去编程,选择 JPA 类似的 ORM,而尽可能的去 SQL 化。

不过写这种工具对 Java 语法树分析,JLS 应该有更深的认识,值得学习。作为 Java 开源项目,我希望:

1 。全面写单元测试
2 。添加 Github Actions CI 集成,或者其它 CI
3 。添加 CodeCoverage 报告,代码质量报告 ,比如挂一个 SonarCloud 集成
hcymk2
2020-11-28 13:12:31 +08:00
hcymk2
2020-11-28 13:16:08 +08:00
接触过多种语言 ORM 。相比较 JOOQ 我更接受 ObjectiveSql 的方式。
php01
2020-11-28 13:43:00 +08:00
啥时候写 java 的数据操作,能像 php 的 laravel 框架的 orm 一样
Braisdom
2020-11-28 14:24:38 +08:00
@hantsy
首先,你先要理解为什么要动态生成,动态生成代码的目的是为了解决重复编码的问题,所谓 OOP 也只是站在简洁的代码基础上的。

OOP 只是一个理论的基础,它无法脱离现实,如果 OOP 会带来太多的重复代码,那么这样的编程也不具备效率。
编程理论有很多种理解的范式,它可以是一份工作,也可以是一份毕业论文,当然也可以是想象中的世界。

我的心中没有面向对象,也没有面向过程,更没有所谓的设计模式,我只有让自身的工作变得简单的想法,很淳朴的想法。若干年后,程序员的职业是否存在都是一个未知数...
Braisdom
2020-11-28 14:28:51 +08:00
@hcymk2 感谢认可,往往认可我项目的人,都是经历过各种 ORM 框架的困扰,我经历太多了,实在忍无可忍了,才下定决心搞一个新的,
VHacker1989
2020-11-28 14:54:13 +08:00
分页太啰嗦了,不如 pagehelper 简洁,建议约定由于配置的原则
Braisdom
2020-11-28 14:54:29 +08:00
@php01 PHP 还是我十几年前写过,已经忘记它是个什么样子了,但我看了 laravel 的框架,还是存在很多问题
1 )模型与模型内的字段,应当是编程中的元素,而不应该是一个字符串
2 )它的很多元语已经脱离结构化的编程,虽然说每种语言都应有自己的编程元语,但在当然,我们应当遵循前人的命名规范,当然可以超越前人的思想
3 )它的表达式,还是不够完美,">",”<“ 这类太过怪异

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

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

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

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

© 2021 V2EX