download:Go Web开发进阶我的项目实战(基于gin框架共81时)
<p>乔克和SPL,基于Java的数据业务逻辑开发技术
很多开源技术都能够在Java下实现以数据库为外围的业务逻辑,其中JOOQ比Hibernate的计算能力更强,比MyBatis的可移植性更好,越来越受到关注。Procspl是一种新的数据计算语言,在计算能力和可移植性方面也有突出的劣势。上面两个方面进行比拟,找出更高效的数据业务逻辑开发技术。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和残缺的调试性能。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很灵便,然而它不太面向对象,应用起来也很麻烦。比方须要通过getValue(M)失去第M个字段。第二种是Record[N]对象,其中N为1到22,如Record3,实用于字段类型和编号已知但不超过22,字段名动静生成的状况。Record[N]不太灵便,但略微更面向对象,所以应用起来更不便。例如,您能够通过valueM获取第m个字段。第三种记录对象是JOOQ的代码工具依据库表构造生成的。几个表中有几个对象,字段的个数、类型、名称与库表中的严格对应,比方OrdersRecord、EmployeesRecord。这种记录对象不灵便,高度面向对象,使用方便,间接通过字段名就能够失去字段。第三类对应的是数据库表,能够称为具备固定数据结构的记录对象。前两类通常来自于数据库表的查问和计算,能够称为具备动静数据结构的记录对象。这三种类型都是罕用的,还有一些不罕用的记录对象,比方用户定义的记录类型UDT,这里就不探讨了。JOOQ中记录的对象品种繁多,用法差别较大,减少了开发难度。这次要是因为业务逻辑中有大量的动静数据结构,而Java是编译语言,只善于表白固定的数据结构。如果保持示意动静数据结构,只能设计简单的接口规定,或者依据字段数量预约义大量对象。
JOOQ记录集的品种绝对较少,比方原生对象后果及其父ArrayList,有时还有Stream。
SPL的结构化数据对象也由记录和记录集(序列表)组成。SPL只有一个记录对象,次要是因为SPL是一种解释性语言。动静数据结构和固定数据结构同样不便表白,接口也很简略,不须要分成多个。此外,记录对象和单个记录集尽管性质不同,但业务含意类似,应用时容易混同。SPL是一种解释性语言,它的内部用法能够通过灵便的接口保持一致,从而进一步提高其可用性。相同,JOOQ是一种编译语言,所以很难设计出如此灵便的接口。它只能提供两种不同的接口,别离用于解决记录对象和单个记录集。
读取数据库
JOOQ读取内部数据库表并生成一个固定的记录集:
Java . SQL . connection conn = driver manager . get connection(URL,用户名,明码);
DSLContext context = DSL . using(conn,SQLDialect。MYSQL);
后果R1=context.select()。来自(订单)。fetchInto(订单);
复制代码
查问内部数据库表以生成动静记录集:
result 2 = context . select(ORDERS。塞利德,命令。客户,订单。金额)。来自(订单)。fetch();
复制代码
动静记录集的后续应用有点麻烦,然而能够兼容固定记录集。以下文章次要应用动静记录集。
SPL读取或查问内部数据库表以生成序列表:
A
一个
=conn=connect("mysql8 ")
2
=conn.query("select * from Orders ")
三
=conn.query("select SellerID,Client,Amount from Orders ")
SPL不分固定记录集和动静记录集,生成办法雷同,后续用法雷同。
写入数据库
为了将解决过的结构化数据对象长久化到数据库中,JOOQ提供了三个函数,即插入、更新和删除。批改记录r并将其更新到数据库:
r.setValue(订单。金额,r.getValue(订单。金额)。double value()+100);
r . update();
复制代码
以上是单个记录的更新。应该留神,数据库表必须有一个主键,这样主动生成的记录类将继承UpdatableRecordImpl。只有继承了UpdatableRecordImpl的record类反对update函数。
写批量数据库是数据业务逻辑的常见场景,JOOQ也能够实现。批改批记录集T并将其更新到数据库:
R1 . foreach(r--> { r . setvalue(ORDERS。金额,r.getValue(订单。金额)。double value()+100);});
R1 . foreach(r--> { r . update();});
复制代码
下面的代码循环记录集,手动更新每条记录,从而实现了整集的更新。如你所见,JOOQ通过硬写代码实现批量编写,没有封装,往往不不便。如果批改、减少或删除一批记录,须要辨别三类记录,而后用不同的函数循环写入。常见的办法是继承record类,增加一个新的“ID”属性来辨别它们,或者保留一个未修改的原始记录集T,手工比拟批改后的集NT和原始集。无论哪种形式,手工实现的过程都很麻烦。
SPL封装了数据库的编写,增加、批改、删除单个和批量记录只应用一个更新函数,反对混合更新。比方原来的序列表是T,通过一系列增删改后的序列表是NT,变更后果长久化到数据库的orders表中:
连贯更新(NT:T,订单)
复制代码
拜访字段
JOOQ读取单个记录的客户端字段:
R1.get(0)。getClient();
R1.get(0)。获取(订单。客户端);
复制代码
下面的代码体现了JOOQ的外围劣势:它反对纯面向对象的字段拜访,并且不混合字符串、数值常量或其余非Java表达式。代码格调高度对立。可怜的是,下面的代码只实用于固定的结构化数据对象。如果是查问计算生成的动静记录对象,只能应用字符串字段名或数字序列号来拜访字段:
R2.get(0)。get(" Client ");
R2.get(0)。get(1);
复制代码
动静记录对象更常见。以上字段的拜访形式不是纯面向对象的,代码格调不统一,不反对主动补全,编写个别比拟麻烦。
SPL反对纯面向对象的字段拜访,不论是固定的还是动静的,个别写起来都很不便:
T(1)。客户
复制代码
当然,也反对字符串字段名或数字序列号来拜访字段:
T(1)。字段(2)
T(1)。现场(“客户”)
复制代码
SPL在面向对象方面更纯正,格调更对立,写代码更不便。此外,SPL提供了许多JOOQ不反对的便捷函数:默认字段名,能够间接用点号拜访,比方取第二个字段:t (1)。# 2;取多个字段,返回一组汇合:t .([客户端,金额])
有序拜访
有序拜访是业务逻辑开发的难点之一。JOOQ的记录集继承了Java的有序集ArrayList,具备肯定的有序拜访能力,反对按下标和按区间取记录:
R.get(3)
R.subList(3,5);
复制代码
进一步的函数须要硬编码,例如最初三个:
collections . reverse(R);
R.subList(0,3);
复制代码
至于依据地位集取记录、向前步进记录等性能。,硬编码就更麻烦了。
SPL程序表也是一个有序集,提供了与程序相干的基本功能,如按下标取数、按区间取数等:
T(3)
转换到(3,5)
复制代码
序列表是业余的结构化数据对象,不反对很多与sequence JOOQ后果相干的高级函数,而序列表是间接提供的。例如,依照倒序号取记录,能够间接用负号示意:
T.m(-3)//倒数第二条
T.m (to (-3,-5))//倒数距离
复制代码
例如,依据地位设置进行记录,并逐渐记录:
T.M (1,3,5,7:10)//序列号为1,3,5,7-10的记录
T.M (-1,-3,-5)//倒数第二条1,3,5
T.step (2,1)//每两个取第一个(相当于奇数地位)
复制代码
结构化数据计算
结构化数据计算能力是数据业务逻辑的外围性能。上面是一些常见的话题,从简略到简单,比拟JOOQ和SPL的计算代码。
重新命名
//等效的SQL
抉择卖方ID eid,订单金额
//JOOQ
context.select(订单。seller id . as(“Eid”),订单。AMOUNT.as(“金额”)。来自(订单)。获取()
//SPL
Orders.new(SellerID:EID,Amount:amt)
复制代码
JOOQ的语法逻辑和SQL基本相同,能够达到用面向对象的形式模仿SQL的目标,这是JOOQ的重要劣势。也有不利之处。JOOQ的一个操作须要几个函数的组合。每个函数都有本人的参数和语法规定,学习和编写都比拟艰难。此外,许多函数中的字段名必须伴有表名,即便对于单表计算也是如此。这阐明JOOQ的语法还不够业余,还有很大的晋升空间。
SPL间接应用面向对象的语法来实现计算。一个操作对应一个函数,援用字段不肯定要带表名。语法更业余,代码更短。
条件查问
//等效的SQL
select * from Orders where
((SellerID=2,Amount=2000,Amount2010
//JOOQ
context.select()。来自(订单)
。其中(
((订单。SELLERID.equal(2)。和(订单。金额小于(3000.0)))
。或者((订单。SELLERID.equal(3)。和(订单。amount . greater requal(2000.0)。和(订单。金额小于(5000.0))))))
。和(年(目。订单日期)。greaterThan(2012)))
。fetch();
//SPL
订单.抉择(
((SellerID = = 2 & & Amount = 2000 & & Amount 2010)
复制代码
SQL自身的条件表达式足够简略。JOOQ尽管是模仿SQL,然而适度封装了条件表达式,函数太多,多括号难读,远不如SQL易懂。SPL应用函数实现条件查问,条件表达式简短易读。
分组摘要
//等效的SQL:
抉择客户,提取(从订单日期开始的年份)y,计数(1) cnt
来自订单
按客户分组,提取(从订购日期开始的年份)
having AMT result = context . select(max(T2 . field(" continuous days "))。来自(T2)。fetch();
复制代码
这个问题比拟难,须要多种简略计算的综合利用。JOOQ很难间接表白间断上涨的概念,只能通过技巧变相实现,即通过累计未上涨天数来计算间断上涨天数。具体来说,按工夫程序用回升标记标记每个记录。如果上涨,标记为1,如果上涨,标记为0;而后按工夫程序累加每条记录不涨的天数,norisingdays。只有当以后记录下降时,这个数字才会减少;如果目前的记录回升,这个数字将放弃不变;依据不再回升的norisingdays数,找出每组的记录数。很显著,一批间断降落的记录的norisingdays的数量是不同的,每个记录会被划分到不同的组中。这个组算1,不是解决问题的指标,而是间断回升的一批记录的norisingdays数雷同,能够分到同一个组。这组统计间断上涨的天数,这个数值就是解决问题的指标。最初用max函数计算最大间断上涨天数。
JOOQ的编程过程是先写SQL,而后翻译成JOOQ。对于简略的计算,SQL更容易写,翻译也不太难。但对于这种综合计算,计算逻辑更有技巧性,SQL不好写,所以翻译难度更大。另外,JOOQ是外表上很容易调试的Java,但实质是SQL,和SQL一样难调试,而这为当前的保护埋下了一个大坑。
SPL电码简略得多:
APPL.sort(天)。[email protected](价格1000)
复制代码
选项也能够组合,例如:
[email protected](金额> 1000)
复制代码
一些函数的参数很简单,能够分为多个档次。JOOQ对此没有非凡的语法计划。只能拆分成多个函数互相嵌套,尽力模仿SQL语法,导致代码简短繁琐。SPL创造性地创造了分层参数来简化简单参数的表白,用分号、逗号、冒号从高到低将参数分为三层。例如,关联两个表:
退出(订单:o,SellerId员工:e,EId)
复制代码
过程
JOOQ反对一些存储过程语法,包含循环语句和判断语句,但属于商业版,因为权限要求高,存在潜在的平安危险,移植起来比拟艰难,所以很少应用。除了存储过程,JOOQ还能够应用Java实现流程解决。对数据库没有权限要求,安全隐患小,能够无缝移植。例如,依据规定计算奖金:
orders . foreach(r--> {
Double amount=r.getValue(订单。金额);
如果(金额> 10000) {
r.setValue(订单。奖金),金额* 0.05);
}else if(金额> =5000 &&金额=2000 &&金额10000,金额*0.05,
如果(金额> 5000 &&金额=2000 &&金额</p>