jooq_jOOQ API设计缺陷的怪异事件
jooq
jOOQ是内部特定于域的语言(DSL) ,它以Java(宿主语言)建模SQL语言(外部DSL)。 这篇热门文章描述了jOOQ API的主要机制:
Java Fluent API设计器速成课程 。
任何人都可以根据该文章中的规则以Java(或大多数其他宿主语言)实现内部DSL。
SQL语言功能示例:BOOLEANs
但是,关于SQL语言的BOOLEAN
是BOOLEAN
类型,该类型在SQL:1999以后才引入到该语言中。 当然,没有布尔值,您可以通过1
和0
建模TRUE
和FALSE
值,并使用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的Condition
和Field<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
jooq_jOOQ API设计缺陷的怪异事件相关推荐
- jOOQ API设计缺陷的奇怪发生
jOOQ是一种内部领域特定语言(DSL) ,它以Java(宿主语言)建模SQL语言(外部DSL). 这篇热门文章描述了jOOQ API的主要机制: Java Fluent API设计器速成课程 . 任 ...
- 人工智能缺陷与误觉:让机器产生幻觉的「怪异事件」
2019独角兽企业重金招聘Python工程师标准>>> 简评:如果人工智能犯了错怎么办? 乘客看到了停车标志,突然感到一阵恐慌,因为他搭乘的自动驾驶汽车反而开始加速. 当他看到前面的 ...
- 人工智能缺陷与误觉:让机器产生幻觉的「怪异事件」 1
简评:如果人工智能犯了错怎么办? 乘客看到了停车标志,突然感到一阵恐慌,因为他搭乘的自动驾驶汽车反而开始加速. 当他看到前面的铁轨上一列火车向他们疾驰而来时,他张开嘴对前面的司机大声喊叫,但他突然意识 ...
- 从达标到卓越 —— API 设计之道
摘要: 新技术层出不穷,长江后浪推前浪.在浪潮褪去后,能留下来的,是一些经典的设计思想. 在前端界,以前有远近闻名的 jQuery,近来有声名鹊起的 Vue.js.这两者叫好又叫座的原因固然有很多,但 ...
- C++ API设计笔记
<C++ API设计>原英文版由Martin Reddy著,中文版出版于2013年,这里是中文版的笔记. 1. API简介 1.1 什么是API:API(Application Progr ...
- C++ API 设计 章节链接
http://www.aiuxian.com/article/p-1301505.html 第三章 模式 前一章所讨论的品质是用来区分设计良好和糟糕的API.在接下来的几个章节将重点关注构建高品质的A ...
- C++ API 设计 08 第三章 模式
第三章 模式 前一章所讨论的品质是用来区分设计良好和糟糕的API.在接下来的几个章节将重点关注构建高品质的API的技术和原则.这个特殊的章节将涵盖一些有用的设计模式和C++ API设计的相关习惯用法. ...
- 【翻译转载】API设计那些事
Henning, Michi. "API design matters." Communications of the ACM 52.5 (2009): 46-56. http ...
- java api 设计_Java API设计实践
使你的API在模块化和非模块化Java环境中都可用 在优锐课的java学习分享中,对微服务有了更深层次的新概念.关于API设计实践一点就通了. 介绍 了解设计Java API时应应用的一些API设计实 ...
最新文章
- Jsp实现网上彩票销售系统
- 如何用CSS制作横向菜单?
- Java 寻找幸运数
- Android布局琐碎(原)
- 编写Thymeleaf视图以展示数据
- php memcache可存,php使用memcache共享存储session(二)
- SAP UI5 CRM Reuse Fiori应用 note.js代码审查结果
- 使用TorchElastic训练DeepSpeech
- php eval 语法错误,PHP eval和捕获错误(尽可能多)
- 三年Java开发,尚学堂java马士兵全套
- 「CH2101」可达性统计 解题报告
- Javascript特效:导航栏楼层效果
- 有趣的JavaScript数组
- 电脑蓝屏分析教程,附工具WinDbg(x86 x64)6.12.0002.633下载
- hdmi线和vga线哪个好?用HDMI线和VGA线,显示屏画质到底相差多大?
- java pointer_Java Pointer.pointerToCString方法代码示例
- Elasticsearch Query DSL 整理总结(查询)
- MQTT与paho.mqtt
- 2020年计算机领域(人工智能、数据库、计算机理论、系统软件、计算机网络等)会议截稿日期大全!(2020年3月份更新)
- 51单片机 Proteus仿真 电烙铁温度保护系统 DS18B20 温度报警系统
热门文章
- 震惊!快速幂怎么编?省一说暴力,银牌说递归,国集听完笑了
- P4258-[WC2016]挑战NPC【带花树】
- CF570D-Tree Requests【长链剖分】
- P5546-[POI2000]公共串【SAM】
- P3389-[模板]高斯消元法
- 欢乐纪中某A组赛【2019.7.12】
- jzoj4671-World Tour【图论,bfs】
- insert ... on duplicate key update产生death lock死锁原理
- Redis PK Memcached,哪个更牛叉
- java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍