当前位置:网站首页>使用jOOQ 3.14合成外键在视图上写隐式连接
使用jOOQ 3.14合成外键在视图上写隐式连接
2022-08-02 05:19:00 【JAVAQXQ】
全的方式浏览你的to-one关系,隐式生成 LEFT JOIN 操作,而不必一直考虑连接谓词,以及正确的连接顺序。考虑一下这个Sakila数据库查询,如果SQL原生支持隐式连接。
SELECT cu.first_name, cu.last_name FROM customer AS cu WHERE cu.address.city.country.country = 'Switzerland' 复制代码
它在本地SQL中被翻译成这个查询。
有需要大厂面经和面试技巧思维导图的朋友可以点进去了解一下,点击——【传送门】——即可!

SELECT cu.first_name, cu.last_name FROM customer AS cu JOIN address AS ad ON cu.address_id = ad.address_id JOIN city AS ci ON a.city_id = ci.city_id JOIN country AS co ON ci.country_id = co.country_id WHERE co.country = 'Switzerland' 复制代码
**注意:**从jOOQ 3.14开始支持内联,这取决于外键是否是强制性的/非空。默认行为是产生 LEFT JOIN ,这是隐式连接可选外键的正确方式。 隐式连接不是银弹。不是每一个 JOIN 图都可以完全转化为隐式连接的用法,也不是每一个隐式连接的用法都比本地SQL JOIN 图更容易阅读。但是有这种选择是很好的。特别是,当你的键是复合键时。
视图上的经典连接
在经典的关系设计中, 代理键经常被避免,而且我认为在很多情况下我们仍然应该避免它们 。即使你不同意,你也可能偶尔会在一个模式上工作,那里很少甚至没有代用键。一个这样的例子是标准的SQL INFORMATION_SCHEMA ,例如在H2、HSQLDB、MariaDB、MySQL、PostgreSQL或SQL Server中实现的。例如,当查询HSQLDB的 DOMAIN_CONSTRAINTS 视图以逆向工程DOMAIN类型。以前的jOOQ查询是这样的。
Domains d = DOMAINS.as("d");
DomainConstraints dc = DOMAIN_CONSTRAINTS.as("dc");
CheckConstraints cc = CHECK_CONSTRAINTS.as("cc");
for (Record record : create()
.select(
d.DOMAIN_SCHEMA,
d.DOMAIN_NAME,
d.DATA_TYPE,
d.CHARACTER_MAXIMUM_LENGTH,
d.NUMERIC_PRECISION,
d.NUMERIC_SCALE,
d.DOMAIN_DEFAULT,
cc.CHECK_CLAUSE)
.from(d)
.join(dc)
.on(row(d.DOMAIN_CATALOG, d.DOMAIN_SCHEMA, d.DOMAIN_NAME)
.eq(dc.DOMAIN_CATALOG, dc.DOMAIN_SCHEMA, dc.DOMAIN_NAME))
.join(cc)
.on(row(dc.CONSTRAINT_CATALOG,
dc.CONSTRAINT_SCHEMA,
dc.CONSTRAINT_NAME)
.eq(cc.CONSTRAINT_CATALOG,
cc.CONSTRAINT_SCHEMA,
cc.CONSTRAINT_NAME))
.where(d.DOMAIN_SCHEMA.in(getInputSchemata()))
.orderBy(d.DOMAIN_SCHEMA, d.DOMAIN_NAME)
) { ... }
复制代码所以,该查询加入了 DOMAINS - DOMAIN_CONSTRAINTS - CHECK_CONSTRAINTS 之间的多对多关系,以获得生成DOMAIN类型所需的所有信息。这些视图是不可更新的,也没有任何与之相关的约束信息,但如果我们能够定义合成约束呢?jOOQ已经支持合成主键,以帮助使视图可更新。
合成外键
从jOOQ 3.14开始,我们重新设计了合成键的工作方式,商业版也将支持合成外键。 你可以像这样指定一个配置。
<configuration> <generator> <database> <syntheticObjects> <primaryKeys> <primaryKey> <tables> CHECK_CONSTRAINTS|CONSTRAINTS|TABLE_CONSTRAINTS </tables> <fields> <field>CONSTRAINT_(CATALOG|SCHEMA|NAME)</field> </fields> </primaryKey> <primaryKey> <tables>DOMAINS</tables> <fields> <field>DOMAIN_(CATALOG|SCHEMA|NAME)</field> </fields> </primaryKey> </primaryKeys> <foreignKeys> <foreignKey> <tables>DOMAIN_CONSTRAINTS</tables> <fields> <field>CONSTRAINT_(CATALOG|SCHEMA|NAME)</field> </fields> <referencedTable>CHECK_CONSTRAINTS</referencedTable> </foreignKey> <foreignKey> <tables>DOMAIN_CONSTRAINTS</tables> <fields> <field>DOMAIN_(CATALOG|SCHEMA|NAME)</field> </fields> <referencedTable>DOMAINS</referencedTable> </foreignKey> </foreignKeys> </syntheticObjects> </database> </generator> </configuration> 复制代码
而jOOQ的代码生成器已经会认为这些视图是表,实际上有下面这样的约束。
ALTER TABLE CHECK_CONSTRAINTS ADD PRIMARY KEY ( CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME ); ALTER TABLE DOMAINS ADD PRIMARY KEY ( DOMAIN_CATALOG, DOMAIN_SCHEMA, DOMAIN_NAME ); ALTER TABLE DOMAIN_CONSTRAINTS ADD FOREIGN KEY ( CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME ) REFERENCES CHECK_CONSTRAINTS; ALTER TABLE DOMAIN_CONSTRAINTS ADD FOREIGN KEY ( DOMAIN_CATALOG, DOMAIN_SCHEMA, DOMAIN_NAME ) REFERENCES DOMAINS; 复制代码
更复杂的配置是可能的,例如为约束分配名称,使用与表内排序不同的字段排序的复合约束,或者外键引用唯一键而不是主键。 关于可用内容的完整描述,请参考手册 。 有了上述可供代码生成器使用的合成元数据,所有众多的好东西现在在视图上也可用,包括。
- 语法 synthetic JOIN .. ON KEY 语法
- 隐式连接
- 生成的TableRecords上的导航方法
- 嵌入式键(另一个令人兴奋的jOOQ 3.14功能)
让我们来看看
隐式连接
隐式连接现在也可以在这些视图上使用,也就是说。
- 你再也不用记住在连接谓词中包括所有的键列了(再见,意外的笛卡尔产品)。
- 即使你的复合键变成了别的东西,你的代码仍然是正确的
所以,这不仅仅是一个方便的事情,它也是一个正确性的事情。我们之前的查询现在可以这样写,以一种更简洁的方式。
DomainConstraints dc = DOMAIN_CONSTRAINTS.as("dc");
for (Record record : create()
.select(
dc.domains().DOMAIN_SCHEMA,
dc.domains().DOMAIN_NAME,
dc.domains().DATA_TYPE,
dc.domains().CHARACTER_MAXIMUM_LENGTH,
dc.domains().NUMERIC_PRECISION,
dc.domains().NUMERIC_SCALE,
dc.domains().DOMAIN_DEFAULT,
dc.checkConstraints().CHECK_CLAUSE)
.from(dc)
.where(dc.domains().DOMAIN_SCHEMA.in(getInputSchemata()))
.orderBy(dc.domains().DOMAIN_SCHEMA, dc.domains().DOMAIN_NAME)
) { ... }
复制代码注意我们是如何使用关系表作为唯一的表放在 FROM 子句中的。这样,我们就可以从 DOMAIN_CONSTRAINTS -> DOMAINS 和 DOMAIN_CONSTRAINTS -> CHECK_CONSTRAINTS 两个方向的对一关系中进行导航。由此产生的SQL查询等同于之前的查询,但所有通过3列组合键连接的讨厌的东西都没有了。我个人认为这更有可读性。
未来的工作
到目前为止,只有一对一的关系可以用这种方式来导航。JPQL也提供对多关系的导航,但有一些限制。这是一个滑动的斜坡。当提供to-many关系时,一些用例是显而易见的,但其他的语义就不那么明显了。例如,让 SELECT 子句根据投影列的存在产生更多(或更少)的行并不是一个好主意。这就是为什么到目前为止jOOQ对隐式连接只产生 LEFT JOIN ,因为这将保证隐式连接的列不会因为 INNER JOIN ,不产生任何匹配而减少行数。 尽管如此,在 #7536 中我们仍然可以添加很多东西,包括。
- 在
FROM子句中的隐式对多连接,它们不会引起任何问题。 - DML中的隐式连接
- 支持解析器,以便在 www.jooq.org/translate ,并通过jOOQ的解析器向所有使用jOOQ SQL的人提供这一功能。 ParsingConnection
还有更多!
边栏推荐
- leetcode一步解决链表反转问题
- 如何优化OpenSumi终端性能?
- Block elements, inline elements (elements, span elements)
- 卸载redis
- 软件测试的需求人才越来越多,为什么大家还是不太愿意走软件测试的道路?
- 21 Day Learning Challenge Schedule
- 线程基础(一)
- 51 microcontroller peripherals article: dot-matrix LCD
- Home NAS server (4) | MergerFS and SnapRaid data backup
- Important concepts of target detection - IOU, receptive field, hole convolution, mAP
猜你喜欢

DNS的解析流程

Use the browser's local storage to realize the function of remembering the user name

引领需求 为HR价值正名——“人力资源领先模型HRLM”成功首发

Polar Parametrization for Vision-based Surround-View 3D Detection Paper Notes

There are more and more talents in software testing. Why are people still reluctant to take the road of software testing?

eggjs controller层调用controller层解决方案

人工神经网络

About the directory structure of the web application

pytorch basic operations: classification tasks using neural networks

Alluxio为Presto赋能跨云的自助服务能力
随机推荐
25K test old bird's 6-year experience in interviews, four types of companies, four types of questions...
线程基础(一)
软件测试在职2年跳槽4次,你还在怪老板不给你涨薪?
Mysql数据库 | 基于Docker搭建Mysql-8.0以上版本主从实例实战
目标检测重要概念——IOU、感受野、空洞卷积、mAP
反向解析dns服务器
网安学习-内网渗透4
leetcode每天5题-Day04
MarkDown公式指导手册
点云旋转到参考坐标系方向(最小方向包围盒方法)
Detailed installation and configuration of golang environment
51 microcontroller peripherals article: dot-matrix LCD
zabbix自动发现和自动注册
Polar Parametrization for Vision-based Surround-View 3D Detection 论文笔记
C语言操作符详解(2)
科技赋能拉萨之“肺”,华为助力拉鲁湿地智慧管理守护绿水青山
【漫画】2021满分程序员行为对照表(最新版)
关于 VS Code 优化启动性能的实践
C language entry combat (13): decimal number to binary
Redis(十一) - 异步优化秒杀