在今年元旦那天宣布了Orca ORM框架的开发《给程序员的新年礼物》。如今已过两月有余,给大家更新一下开发状态,也介绍一下技术路线。

开发状态

近期主要在编写框架的核心逻辑,已支持H2和MySQL数据库,这两天成功把它在Spring Boot应用程序中运行起来了。最主要的技术挑战,即“循环关联的JOIN”,已得到解决。解决这一挑战所花的时间比预期多很多(重做了N次),因此整个项目进度都延后,但是以后都是坦途了。
现在要做的是打磨粗糙边缘和添加实用功能,具体而言是做这些事:

  1. 完善API,编写相应示例
  2. 支持PostgreSQL数据库
  3. 做好事务和连接的管理,与Spring Boot做集成
  4. 优化自动建表流程,与Flyway做集成
  5. 提供一款可视化的模型设计器
  6. 发布工件到公共仓库,进入正式的版本管理

没有什么技术难度了,最重要的就是把API设计好。

技术路线

Orca ORM是一款纯自研的Java ORM框架,旨在取代JPA (Hibernate)等一众现有的ORM框架,主要特性在《给程序员的新年礼物》中有所介绍。它同时也是将来可能推出的“数据引擎”的基石。“数据引擎”的介绍参见《企业应用平台的六大引擎》,它对标Microsoft Dataverse,“企业应用平台”则对标Microsoft Power Platform。微软的这套技术是专有的,如果我们提供一套开源的,大家会喜欢吗?

Ruby的ActiveRecord是ORM框架的登峰造极之作,Orca的API设计在很大程度上参考了ActiveRecord(在将来的文章中可以详细介绍API设计)。由于Java语言的元编程灵活性相对较低,Java社区并没有真正对标ActiveRecord的框架。要提高Java语言的元编程能力,有动态代理、字节码编织、源代码生成这三大技术路线。

  • JPA走的是动态代理路线,但有诸多问题,所以近年来也在转向字节码编织路线(EclipseLink 2.4版本起,Hibernate 5.2版本起)。
  • Ebean是一款介于JPA和ActiveRecord之间的ORM框架,采用了字节码编织的路线来提供接近于Ruby的元编程能力,但是需要在构建脚本中添加插件才能启用相应能力。但是Ebean和JPA的插件都只支持Ant、Maven和Gradle,不支持Bazel。那么Bazel用户就只能在启动脚本中添加javaagent参数,降低了这一技术路线的泛用性。如果Spring Boot能支持no javaagent LTW,字节码编织路线就可以更便利。
  • 源代码生成路线很少被用于ORM框架,但是已活跃在Thrift、gRPC等RPC框架中,它生成的代码是可读的、而且能生成新的接口,不像字节码编织路线会生成不可读的代码、而且只能实现已有的接口。再者,源代码生成路线更适合低代码开发模式(这正是Orca想要支持的)。我们也曾试制过基于字节码编织的ORM框架,但现在,考虑到Bazel用户和低代码开发用户,我们认为源代码生成路线更好,而且我们的终极目标是在线的无代码开发,大多数时候甚至不需要任何代码。如果大家认为字节码编织路线更好,可以进一步交流讨论。

Orca强调领域驱动设计。传统ORM框架没有考虑到领域驱动设计。例如JPA (Hibernate)只是提供了一对一、一对多、多对一、多对多等关联类型,以及各种级联类型。在设计一款业务系统时,应用开发者往往需要自行组合这些类型:实体之间是怎么关联的?什么时候要级联?这都是比较复杂的。

  • 其实从领域驱动设计的角度来看:一对一和一对多都属于“聚合”(Aggregate)关联,左侧的实体“拥有”右侧的实体,或者说右侧的实体“从属于”左侧的实体,应当有从左到右的单向级联;多对一和多对多则属于普通的“引用”(Reference)关联,没有从属关系,不需要级联。
  • 再从类型的角度来看:一对一和多对一都属于“单数”(Singular)关联,关联字段的类型是目标实体类(target entity class);一对多和多对多都属于“复数”(Plural)关联,关联字段的类型是目标实体类的集合。

这样就很简单了:框架不需要提供所有的组合选项,对于一个关联,只需要声明它是聚合还是引用、是单数还是复数,这就够用了。领域驱动设计简化了业务系统的设计。

总之,Orca想汇聚ActiveRecord和JPA的优点,原生支持领域驱动设计,并且增加低代码和无代码开发能力。虽然不容易做到,但值得一试,做了才知道。


sorra
841 声望78 粉丝