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

jooq_jOOQ API设计缺陷的怪异事件相关推荐

  1. jOOQ API设计缺陷的奇怪发生

    jOOQ是一种内部领域特定语言(DSL) ,它以Java(宿主语言)建模SQL语言(外部DSL). 这篇热门文章描述了jOOQ API的主要机制: Java Fluent API设计器速成课程 . 任 ...

  2. 人工智能缺陷与误觉:让机器产生幻觉的「怪异事件」

    2019独角兽企业重金招聘Python工程师标准>>> 简评:如果人工智能犯了错怎么办? 乘客看到了停车标志,突然感到一阵恐慌,因为他搭乘的自动驾驶汽车反而开始加速. 当他看到前面的 ...

  3. 人工智能缺陷与误觉:让机器产生幻觉的「怪异事件」 1

    简评:如果人工智能犯了错怎么办? 乘客看到了停车标志,突然感到一阵恐慌,因为他搭乘的自动驾驶汽车反而开始加速. 当他看到前面的铁轨上一列火车向他们疾驰而来时,他张开嘴对前面的司机大声喊叫,但他突然意识 ...

  4. 从达标到卓越 —— API 设计之道

    摘要: 新技术层出不穷,长江后浪推前浪.在浪潮褪去后,能留下来的,是一些经典的设计思想. 在前端界,以前有远近闻名的 jQuery,近来有声名鹊起的 Vue.js.这两者叫好又叫座的原因固然有很多,但 ...

  5. C++ API设计笔记

    <C++ API设计>原英文版由Martin Reddy著,中文版出版于2013年,这里是中文版的笔记. 1. API简介 1.1 什么是API:API(Application Progr ...

  6. C++ API 设计 章节链接

    http://www.aiuxian.com/article/p-1301505.html 第三章 模式 前一章所讨论的品质是用来区分设计良好和糟糕的API.在接下来的几个章节将重点关注构建高品质的A ...

  7. C++ API 设计 08 第三章 模式

    第三章 模式 前一章所讨论的品质是用来区分设计良好和糟糕的API.在接下来的几个章节将重点关注构建高品质的API的技术和原则.这个特殊的章节将涵盖一些有用的设计模式和C++ API设计的相关习惯用法. ...

  8. 【翻译转载】API设计那些事

    ​ Henning, Michi. "API design matters." Communications of the ACM 52.5 (2009): 46-56. http ...

  9. java api 设计_Java API设计实践

    使你的API在模块化和非模块化Java环境中都可用 在优锐课的java学习分享中,对微服务有了更深层次的新概念.关于API设计实践一点就通了. 介绍 了解设计Java API时应应用的一些API设计实 ...

最新文章

  1. Jsp实现网上彩票销售系统
  2. 如何用CSS制作横向菜单?
  3. Java 寻找幸运数
  4. Android布局琐碎(原)
  5. 编写Thymeleaf视图以展示数据
  6. php memcache可存,php使用memcache共享存储session(二)
  7. SAP UI5 CRM Reuse Fiori应用 note.js代码审查结果
  8. 使用TorchElastic训练DeepSpeech
  9. php eval 语法错误,PHP eval和捕获错误(尽可能多)
  10. 三年Java开发,尚学堂java马士兵全套
  11. 「CH2101」可达性统计 解题报告
  12. Javascript特效:导航栏楼层效果
  13. 有趣的JavaScript数组
  14. 电脑蓝屏分析教程,附工具WinDbg(x86 x64)6.12.0002.633下载
  15. hdmi线和vga线哪个好?用HDMI线和VGA线,显示屏画质到底相差多大?
  16. java pointer_Java Pointer.pointerToCString方法代码示例
  17. Elasticsearch Query DSL 整理总结(查询)
  18. MQTT与paho.mqtt
  19. 2020年计算机领域(人工智能、数据库、计算机理论、系统软件、计算机网络等)会议截稿日期大全!(2020年3月份更新)
  20. 51单片机 Proteus仿真 电烙铁温度保护系统 DS18B20 温度报警系统

热门文章

  1. 震惊!快速幂怎么编?省一说暴力,银牌说递归,国集听完笑了
  2. P4258-[WC2016]挑战NPC【带花树】
  3. CF570D-Tree Requests【长链剖分】
  4. P5546-[POI2000]公共串【SAM】
  5. P3389-[模板]高斯消元法
  6. 欢乐纪中某A组赛【2019.7.12】
  7. jzoj4671-World Tour【图论,bfs】
  8. insert ... on duplicate key update产生death lock死锁原理
  9. Redis PK Memcached,哪个更牛叉
  10. java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍