很多开源技术都可以在Java下实现以数据库为核心的业务逻辑,其中JOOQ的计算能力比Hibernate强,可移植性比MyBatis强,受到越来越多的关注。esProc SPL是新晋的数据计算语言,同样在计算能力和可移植性方面优势突出。下面对二者进行多方面的比较,从中找出开发效率更高的数据业务逻辑开发技术。JOOQ商业版主要支持了商业数据库和存储过程,不在此次讨论范围。
语言特征
##编程风格
JOOQ支持完整的面向对象的编程风格,可以将多个对象(方法)组合起来,形成类似SQL的语法逻辑。JOOQ可以使用Java的Lambda表达式、函数调用接口和流程控制语法,理论上也支持面向函数和面向过程,但这些表达式\语法没有为JOOQ的结构化数据对象(Result)而设计,使用时还不够方便。
SPL支持面向对象、面向函数、面向过程的编程风格,并进行大幅简化。SPL有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容。SPL的Lambda表达式比SQL更加简单易用,函数调用接口和流程控制语法专为结构化数据对象(序表)而设计,使用更加方便。
##运行模式
JOOQ是编译执行的Java代码,性能高一些,灵活性较差。但JOOQ本身没有计算能力,执行后只生成SQL语句,再交由数据库计算并返回结果,实际性能并不高,有些业务逻辑需要反复读写数据库,性能就更差了。SPL是解释型语言,编码更灵活,相同代码性能会差一点。但是,SPL有不依赖数据库的独立计算能力,无需反复读写数据库,内置大量时间复杂度更低的基础运算,计算性能经常能超过编译型语言。
##外部类库
JOOQ可以引入其他任意的第三方Java类库,用来弥补自身的短板,比如利用Stream增加自己的独立计算能力,但这些类库没有为结构化数据对象而设计,提供的功能比较有限。SPL内置专业的数据处理函数,提供了大量开发效率更高、时间复杂度更低的基本运算,通常不需要外部Java类库,特殊情况可在自定义函数中调用。
##IDE和调试
两者都有图形化IDE和完整的调试功能。JOOQ使用Java IDE,好处是更通用,缺点是没有为数据处理做优化,无法方便地观察结构化数据对象。SPL的IDE专为数据处理而设计,结构化数据对象呈现为表格形式,观察更加方便。
##学习难度
JOOQ需要学习三种语法,SQL、通用Java、JOOQ。其中,SQL的语言能力要高于一般水平,才能转化为JOOQ语法;开发时主要使用JOOQ语法,难度不高,但转化过程较复杂;通用Java的语言能力可以低于一般水平。SPL的目标是简化Java甚至SQL的编码,无论入门学习还是深入开发,难度都不高。但涉及到高性能计算时需要学习较多特有的算法,难度也会提高。
##代码量
SQL擅长结构化数据计算,语法较简练,代码量较低,但为了把SQL翻译成JOOQ,需要引入很多函数,存在过度封装的现象,实际代码量较大。JOOQ的流程控制要借助Java语法,但Java语法没有为结构化数据对象而设计,代码量也不低。
SPL的表达能力强于SQL,远强于JOOQ,可用更低的代码量实现结构化数据计算,SPL的流程处理语句专为结构化数据对象而设计,代码量低于Java。
##结构化数据对象
结构化数据对象用于将数据库表对象化,是数据处理和业务逻辑开发的基础,专业的结构化数据对象可以方便地与数据库交换数据,支持丰富的计算函数,并简化流程处理的难度。
##定义
JOOQ的结构化数据对象由记录和记录集合组成。记录对象的种类很多,第一类是Record对象,适合字段的数量、类型、名字都是动态生成的情况,Record虽然很灵活但面向对象的程度较低,用法比较麻烦,比如要通过getValue(M)来获得第M个字段。第二类是Record[N]对象,N从1到22,比如Record3,适合字段类型和字段数量已知但不超过22个,而字段名是动态生成的情况,Record[N]灵活性差些但面向对象的程度稍高,用法方便些,比如可以通过valueM取得第M个字段。第三类记录对象由JOOQ的代码工具根据库表结构生成,有几个表就有几个对象,字段的数量、类型、名字都和库表字段严格对应,比如OrdersRecord、EmployeesRecord,这种记录对象不灵活但面向对象的程度很高,用法也很方便,可以直接通过字段名取字段。第三类对应库表,可称之为固定数据结构的记录对象,前两类通常来自对库表的查询计算,可称之为动态数据结构的记录对象。这三类比较常用,还有些不常用的记录对象,比如用户自定义记录类型UDT,这里就不展开说了。JOOQ的记录对象种类繁多,用法差异较大,增加了开发的难度,这主要因为业务逻辑存在大量动态数据结构,而Java是编译型语言,只擅长表达固定数据结构,如果硬要表达动态数据结构,就只能设计复杂的接口规则,或者根据字段数量预定义大量对象。
JOOQ记录集合的种类相对较少,常用的有原生对象Result,及其父类ArrayList,有时候也会用Stream。
SPL的结构化数据对象同样由记录(Record)和记录集合(序表)组成。SPL的记录对象只有一种,主要因为SPL是解释型语言,动态数据结构和固定数据结构表达起来同样方便,接口都很简单,没必要分成多个。此外,记录对象与单记录集合虽然本质不同,但业务意义相似,用起来容易混淆。SPL是解释型语言,可以通过灵活的接口使两者的外部用法保持一致,从而进一步提高易用性。相反,JOOQ是编译型语言,很难设计出这种灵活的接口,只能提供两类不同的接口&#