jOOQ API设计缺陷的奇怪发生

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

Java Fluent API设计器速成课程 。

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

SQL语言功能示例:BOOLEAN

但是,关于SQL语言的优点之一是BOOLEAN类型,该类型在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)方法可能是个好主意,在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

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

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

相关文章

精馏塔matlab,MATLAB图解精馏塔理论塔板数程序代码

《MATLAB图解精馏塔理论塔板数程序代码》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《MATLAB图解精馏塔理论塔板数程序代码(6页珍藏版)》请在人人文库网上搜索。1、MATLAB图解精馏塔理论塔板数程序代码function distillation %文件名“distillation”可以更改% 输入…

c# 衍生类和基类的构造顺序

public class MyDeriveClass:MyBaseClass{public MyDeriveClass():base(){}int derive_int 1;}public class MyBaseClass{public MyBaseClass(){}int base_int 1;} var cls new MyDeriveClass(); 调用顺序如下: derive_int 1;base_int 1;MyBaseClass(); MyDeriveClass();…

oracle unused用法,set unused的用法(ORACLE刪除字段)

set unused的用法(ORACLE刪除字段)一、問題現場有一張大數據量的分區表&#xff0c;數據量在10G以上。因某種原因需要刪除其中的某些字段。如果直接用alter table1 drop (column1,column2);或者alter table1 drop column column1;和alter table1 drop column column2;的話&…

java 计算协方差_Java的深度:通过协方差暴露的API泄漏

java 计算协方差Java有时可能非常棘手&#xff0c;特别是在API设计中。 让我们看一个非常有趣的展示柜。 jOOQ强烈地将API与实现分开。 所有API都在org.jooq包中&#xff0c;并且是公共的。 大多数实现是在org.jooq.impl包和package-private中。 只有工厂和一些专用的基础实现是…

shell启动oracle客户端,Shell实现的Oracle启动脚本分享

Usage: sh oracled [start|stop|restart] SIDs 其中SIDs是数据库名&#xff0c;多个名称之间用逗号分隔。缺省的操作是 restart &#xff0c;也可以指定需要进行的操作( start | stop | restart )#!/bin/shcmdname"restart"# get oracle sid information from env by…

使用Java 8 Lambda,流和聚合

总览 在本文中&#xff0c;我们将介绍使用Java 8 lambda&#xff0c;流和聚合来过滤和操作Collection中的对象。 这篇文章中的所有代码都可以在BitBucket中找到 。 在此示例中&#xff0c;我们将创建许多对象&#xff0c;这些对象代表我们IT基础架构中的服务器。 我们将这些对…

易语言微凉模块oracle,跟着微凉学易语言 【简单子类化】

本帖最后由 【微凉清风】 于 2011-1-20 18:23 编辑易语言的子类化文章太少了,本人文笔也不好哈,看看VB得吧,别说英文看不懂,看不懂你的易语言水平永远不会提高!一,初识子类当你还不碰过子类的时候,你看到这个标题,定会问:"啥叫子类?".因为你知道我定会为你解答.(阴险…

node服务的监控预警系统架构

需求背景 目前node端的服务逐渐成熟&#xff0c;在不少公司内部也开始承担业务处理或者视图渲染工作。不同于个人开发的简单服务器&#xff0c;企业级的node服务要求更为苛刻&#xff1a; 高稳定性、高可靠性、鲁棒性以及直观的监控和报警 想象下一个存在安全隐患且没有监控预警…

oracle中or会使索引,为何查询条件中多了 OR 选项,索引就走全扫描?

ORACLE 11204, SOLARIS如下&#xff1a;原始写法&#xff0c;where 条件中&#xff0c;有 OR 条件&#xff0c;这时&#xff0c;索引 IDX_BD_LOTMASTER_NO 走全索引扫描&#xff0c;导致效率非常低&#xff0c;-bash-3.2$ sqlplusSQL*Plus: Release 11.2.0.4.0 Production on…

C# 热敏打印机 Socket 网络链接 打印 图片 (二)

1 IPAddress ip IPAddress.Parse("192.168.1.212"); 2 IPEndPoint iport new IPEndPoint(ip, 9100);//9100为小票打印机指定端口 3 Socket soc new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 4 …

oracle自动内存管理要不要开,Oracle 11g的自动内存管理

Oracle 的 9i/10g 中已经对内存管理逐步做了很大的简化&#xff0c;11g 则更进一步&#xff0c;引入了一个新的概念自动化内存管理(Automatic Memory Management,AMM) . 如果 DBA 真的想偷懒的话&#xff0c;只需要设定两个参数就可以把烦心的事情都交给 Oracle 折腾了(只要 DB…

jaxb util_JAXB自定义绑定– Java.util.Date / Spring 3序列化

jaxb utilJaxB可以处理Java.util.Date序列化&#xff0c;但是需要以下格式&#xff1a; “ yyyy-MM-ddTHH&#xff1a;mm&#xff1a;ss ”。 如果需要将日期对象格式化为另一种格式怎么办&#xff1f; 我有同样的问题时&#xff0c;我正在同春MVC 3和Jackson JSON处理器 &…

いちがつ(2017/1)

org.apache.ibatis.builder.IncompleteElementException: Could not find parameter map com.enjoyor.soa.traffic.core.tms.mapper.MarkingInfoMapper.Map mybatis的xml配置文件中没有配置parameter map。 要么配置parameter map 要么将select,add等属性中的parameter map 改…

oracle数据库没有选项,创建oracle数据库时,出现ORA-00922: 选项缺失或无效

sdd53HOME新建oracle数据库时遇到ORA-00922: 选项缺失或无效的问题&#xff0c;如图&#xff1a;原因&#xff1a;一般是语句的语法有问题。比如命名不对&#xff0c;关键字写错等等。对于非标准的命名&#xff0c;一般采用双引号来创建。具体原因&#xff1a;就是开始的用户密…

set和enum类型的用法和区别

mysql中的set和enum类型的用法和区别 mysql中的enum和set其实都是string类型的而且只能在指定的集合里取值, 不同的是set可以取多个值,enum只能取一个值。 12345678910111213[php] CREATE TABLE 20121101_t ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(20) N…

Java EE 8 MVC:使用查询参数

在上一篇有关新Java EE MVC框架的文章中&#xff0c;我们详细介绍了Controllers 。 在本篇和以下文章中&#xff0c;我们将看到如何在MVC控制器中访问各种类型的请求数据。 Java EE MVC大量使用了JAX-RS&#xff0c;我们将在本篇和下一篇文章中看到的大多数内容都是JAX-RS的功…

oracle 10g r2 for solaris x86,Oracle10g for Solaris9(x86)安装指南

Oracle10g for Solaris9(x86)安装指南一、安装环境检查&#xff1a;机器环境&#xff1a;cpu:P41.7G&#xff0c;内存:1G&#xff1b;OS&#xff1a;Windows 2000 Advaced Server(sp4)虚拟机系统平台&#xff1a;Vmware Workstation4.5.2Solaris9(x86)虚拟机资源分配&#xff1…

百度脑图

1.地址&#xff1a;http://naotu.baidu.com/ 2.简介&#xff1a;在线创作思维导图。 3.优势&#xff1a; 3.1在线使用&#xff0c;学习成本低。 3.2有多种导图展示方式。 4.缺点&#xff1a; 4.1只有思维导图一种形式比较单一转载于:https://www.cnblogs.com/hmdlys/p/6252071.…

oracle 导出 cuow,直通伍伦贡大学的升学保障— 伍伦贡大学学院(UOWC)

伍伦贡大学学院是直属大学的桥梁课程提供者&#xff0c;为没有达到直入本科的学生提供另一种进入大学的途径&#xff0c;也为大学提供语言类课程。自1989年成立以来&#xff0c;为大学输送了数以千计的优秀学生。目前学院有来自世界30多个国家超过2000名在校生。在伍伦贡大学学…

async 和 await 的进阶

异常的捕获&#xff1a; static void Main(string[] args){//继续我们的异步编程的使用嘀呀&#xff1b;//关于主线程是无法捕获我们子线程中的异常滴滴啊&#xff1b;var t DoExceptionAsync();t.Wait();Console.WriteLine($"{nameof(t.Status)}: {t.Status}"); …