jooq_jOOQ API设计缺陷的怪异事件

jooq

jOOQ是内部特定于域的语言(DSL) ,它以Java(宿主语言)建模SQL语言(外部DSL)。 这篇热门文章描述了jOOQ API的主要机制:

Java Fluent API设计器速成课程 。

任何人都可以根据该文章中的规则以Java(或大多数其他宿主语言)实现内部DSL。

SQL语言功能示例:BOOLEANs

但是,关于SQL语言的BOOLEANBOOLEAN类型,该类型在SQL:1999以后才引入到该语言中。 当然,没有布尔值,您可以通过10建模TRUEFALSE值,并使用CASE将谓词转换为值

CASE WHEN A = B THEN 1 ELSE 0 END

但是有了真正的BOOLEAN支持,您可以进行出色的查询,例如针对Sakila数据库运行的以下PostgreSQL查询:

SELECTf.title, string_agg(a.first_name, ', ') AS actors
FROM film AS f
JOIN film_actor AS fa USING (film_id)
JOIN actor AS a USING (actor_id)
GROUP BY film_id
HAVING every(a.first_name LIKE '%A%')

以上收益:

TITLE                    ACTORS
-----------------------------------------------------
AMISTAD MIDSUMMER        CARY, DARYL, SCARLETT, SALMA
ANNIE IDENTITY           CATE, ADAM, GRETA
ANTHEM LUKE              MILLA, OPRAH
ARSENIC INDEPENDENCE     RITA, CUBA, OPRAH
BIRD INDEPENDENCE        FAY, JAYNE
...

换句话说,我们正在寻找所有电影,其中在电影中扮演过的所有演员的名字中都包含字母“ A”。 这是通过布尔表达式/谓词first_name LIKE '%A%'上的聚合来完成first_name LIKE '%A%'

HAVING every(a.first_name LIKE '%A%')

现在,按照jOOQ API的术语,这意味着我们必须提供having()不同参数类型的hading having()方法的重载,例如:

// These accept "classic" predicates
having(Condition... conditions);
having(Collection<? extends Condition> conditions);// These accept a BOOLEAN type
having(Field<Boolean> condition);

当然,这些重载可用于任何接受谓词/布尔值的API方法,而不仅仅是HAVING子句。

如前所述,从SQL:1999开始,jOOQ的ConditionField<Boolean>确实是同一回事。 jOOQ允许通过显式API在两者之间进行转换:

Condition condition1 = FIRST_NAME.like("%A%");
Field<Boolean> field = field(condition1);
Condition condition2 = condition(field);

…和重载使转换更方便地隐式进行。

所以有什么问题?

问题在于,我们认为最好再添加一个方便的重载,即having(Boolean)方法,为了方便起见,可以在查询中引入常量,可为空的BOOLEAN值,这在构建动态SQL时非常有用。 ,或注释掉某些谓词:

DSL.using(configuration).select().from(TABLE).where(true)
// .and(predicate1).and(predicate2)
// .and(predicate3).fetch();

这个想法是,无论您要临时删除哪个谓词,都不会将WHERE关键字注释掉。

不幸的是,添加此重载给使用IDE自动完成功能的开发人员带来了麻烦。 考虑以下两个方法调用:

// Using jOOQ API
Condition condition1 = FIRST_NAME.eq   ("ADAM");
Condition condition2 = FIRST_NAME.equal("ADAM");// Using Object.equals (accident)
boolean = FIRST_NAME.equals("ADAM");

通过(偶然地)在equal()方法中添加字母“ s” equal()主要是由于IDE自动完成功能),整个谓词表达式从可用于生成SQL的jOOQ表达式树元素到“普通”布尔值,都大大改变了语义。值(显然总是产生false )。

在添加最后一个重载之前,这不是问题。 equals()方法的用法无法编译,因为没有适用的重载采用Java boolean类型。

// These accept "classic" predicates
having(Condition condition);
having(Condition... conditions);
having(Collection<? extends Condition> conditions);// These accept a BOOLEAN type
having(Field<Boolean> condition);// This method didn't exist prior to jOOQ 3.7
// having(Boolean condition);

在jOOQ 3.7之后,由于编译器不再抱怨,导致错误SQL,这种事故开始在用户代码中引起注意。

您继承了宿主语言的“缺陷”

Java是“有缺陷的”,因为可以保证每种类型都继承自java.lang.Object及其方法: getClass()clone()finalize() equals()hashCode()toString()notify()notifyAll()wait()

在大多数API中,这实际上并不是什么大问题。 您实际上并不需要重用上述任何方法名(请不要) 。

但是在设计内部DSL时,这些Object方法名称(就像language关键字一样)限制了您的设计空间。 在equal(s)的情况下,这一点尤其明显。

我们已经学习,并且已经弃用,并且将移除having(Boolean)重载 ,并再次移除所有类似的重载。

翻译自: https://www.javacodegeeks.com/2016/01/curious-incidence-jooq-api-design-flaw.html

jooq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux镜像文件不要大于4g,Systemback制做大于4G的Ubuntu系统镜像

1 安装Systemback依此执行以下命令。sudo apt-get updatesudo add-apt-repository ppa:nemh/systembacksudo apt-get update && sudo apt-get install systemback unionfs-fuse安装完成&#xff1a;2 使用Systemback生成镜像文件输入管理员密码&#xff0c;打开后界面以…

黑马2016java_2016年成功的Java开发人员简介

黑马2016java2015年即将结束。 现在该总结过去一年中已完成的工作和未完成的工作。 此外&#xff0c;现在是预测下一个2016年的好时机。 您已经猜到这篇文章是关于2016年理想的Java开发人员的。 我想给你一个惊喜&#xff0c;这次我更改了预测的格​​式。 为了使预测更加客观…

红帽子linux笔试题,redhat-linux面试题

redhat-linux面试题1. 在Linux系统中&#xff0c;以 &#xff3f;文件&#xff3f;&#xff3f; 方式访问设备 。2. Linux内核引导时&#xff0c;从文件 /etc 中读取要加载的文件系统。3. Linux文件系统中每个文件用&#xff3f;节点&#xff3f;&#xff3f;来标识。4. 链接分…

lambda设计模式_使用lambda的装饰器设计模式

lambda设计模式随着Java中lambda的出现&#xff0c;我们现在有了一个新工具&#xff0c;可以更好地设计我们的代码。 当然&#xff0c;第一步是使用流&#xff0c;方法引用和Java 8中引入的其他简洁功能。 展望未来&#xff0c;我认为下一步是重新访问完善的设计模式&#xff…

linux监控nginx占用,使用zabbix 2.4 监控nginx

1、获取 Nginx 状态( HTTP Stub Status )/usr/local/nginx/sbin/nginx -V2、配置 nginx.confvim /usr/local/nginx/conf/nginx.conflocation ~ /nginx_status {stub_status on;access_log off;allow 127.0.0.1;allow 192.168.1.14;deny all;}3、编写脚本获取上面的 key 值vim /…

如何使用java代码生成_使用Java成功生成代码的7个技巧

如何使用java代码生成作为介绍&#xff0c;最近我有点安静&#xff0c;部分原因是我一直在忙于Chronicle-FIX的工作 。 这是Chronicle-Enterprise套件中的一个新的超低延迟库&#xff0c;我们证明了该库可以在低个位数微秒内解析和存储消息。 当然&#xff0c;它利用了我们的开…

多核 linux 绑定,Linux 操作系统下CPU多核心的绑定

现在多CPU的趋势越来越大了. 有时候为了更好地操作机器, 需要将某个进程绑定到具体的CPU上去. 下面给出了一个进程绑定到具体的CPU上去的一个例子.cpu.c[CODE]#include#include#include#include#include#define __USE_GNU#include#include#includeint main(int argc, char* arg…

java键盘事件键值表_Java的20年:重大事件的时间表

java键盘事件键值表翻译自: https://www.javacodegeeks.com/2015/12/2-decades-java-timeline-notable-events.htmljava键盘事件键值表

c语言printf到指定文件,急求如何将下列C语言程序数据存储到文件中?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼求如何改动才能将下列程序的存储输入或输出数据(或两者一起)到指定的文件(或运行时直接创立一个文件)如Arrangement中。#include int n0;int rest[7][7]; //全局声明,以供全局调用int main(){void perm(int list[],int ,int );int …

spring一站式开发_Spring开发人员知道的一件事

spring一站式开发在最近的&#xff08;核心&#xff09;Spring框架培训课程中&#xff0c;有人问我&#xff1a;“&#xff08;Java&#xff09;Spring开发人员应该知道的一件事是什么&#xff1f;” 这个问题使我措手不及。 是的&#xff0c;&#xff08;核心&#xff09;Spri…

c语言十六进制转换加H,c语言十六进制和十进制间的转换.docx

集团文件版本号&#xff1a;(M928-T898-M248-WU2669-I2896-DQ586-M1988)集团文件版本号&#xff1a;(M928-T898-M248-WU2669-I2896-DQ586-M1988)c语言十六进制和十进制间的转换1.将十六进制转换为十进制.#include#includeint main(void){int convert(int,char *);int i,j;char …

jax-ws和jax-rs_带有JAX-WS和Spring的Web服务应用程序

jax-ws和jax-rs1.简介 这是一个漫长的等待&#xff0c;但是我最终要发布有关使用Spring创建第一个基于SOAP的Web服务应用程序的教程。 JAX-WS &#xff08;用于XML Web服务的Java API&#xff09;是用于以XML格式创建Web服务的一组API&#xff0c;我们最常将其称为基于SOAP的We…

c command语言学例子,语言学第四章

《语言学第四章》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《语言学第四章(3页珍藏版)》请在人人文库网上搜索。1、Chapter 4:SyntaxI. Decide whether each of the following statements is True or False:1. Syntax is a subfield of linguistics that studies …

eclipse开发jsf_在Eclipse上创建JSF / CDI Maven项目

eclipse开发jsf当我在研究JSF和CDI示例时&#xff0c;我认为提到创建JSF和CDI Maven项目所需的步骤会很有用。 您可以找到以下步骤。 工具类 默认情况下&#xff0c;M2E插件随附的Eclipse Luna。 因此&#xff0c;无需自己安装插件。 WildFlye8.x。 从主菜单中选择文件->…

apache camel_Apache Camel的性能调整思路

apache camel时不时地&#xff0c;我会以Camel速度较慢的观点来询问有关优化Camel应用程序的问题。 骆驼只是连接不同系统的粘合剂&#xff0c;路由引擎全部在内存中&#xff0c;并且不需要任何持久状态。 因此&#xff0c;在99&#xff05;的情况下&#xff0c;性能问题是由于…

为什么写C语言弹不出窗口,居然还有SB说C写不出窗口的..

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼decebx.endwassumeesi:nothinginvokeGetStockObject,WHITE_BRUSHinvokeSelectObject,hDcBack,eaxinvokeDeleteObject,eaxinvokeDeleteObject,hBmpBackpopadret_CreateBackGroundendp;>>>>>>>>>>>…

java写入单个字符_将2个字符写入单个Java char

java写入单个字符这是创建超低延迟的Chronicle FIX-Engine时使用的另一个好技巧。 在从字节流中读取数据时&#xff0c;如果可能的话&#xff0c;将数据存储在char而不是将其读取到String效率更高。 &#xff08;至少您要避免创建String对象&#xff0c;尽管可以通过使用缓存或…

xmanager linux,教您用xmanager启动Linux上的图形界面程序-Go语言中文社区

对于习惯实体化的开发人员来说&#xff0c;还是界面化用着比较习惯&#xff0c;所以这就涉及到掌握使用Xmanager启动Linux上的图形界面程序&#xff0c;为了方便大家的使用&#xff0c;本集小编就详细的为大家讲解具体操作。具体步骤如下&#xff1a;1、首先下载Xmanager并安装…

android开发 文件分享到应用,Android 实现文件分享功能(共享多个文件)

效果如图&#xff1a;神一样的代码&#xff1a;针对image代码如下&#xff1a;IntentsharenewIntent(Intent.ACTION_SEND);share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));//此处一定要用Uri.fromFile(file),其中file为File类型&#xff0c;否则附件无法发送成功。s…

python kotlin_用Java和Python模仿Kotlin构建器

python kotlin介绍 Kotlin可能现在是我最喜欢的语言&#xff0c;可能它提供的最酷的功能之一是基于几个功能构建的类型安全的生成器&#xff08;稍后解释&#xff09;。 我发现自己真的很想在其他两种主要语言&#xff08;Java和Python&#xff09;中使用此功能。 本文解释了我…