当前位置:网站首页>使用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
还有更多!
边栏推荐
- BGP实验(路由反射器,联邦,路由优化)
- 18 years of programmer career, read more than 200 programming books, pick out some essence to share with you
- HCIP BGP综合实验 建立对等体、路由反射器、联邦、路由宣告及聚合
- Alluxio为Presto赋能跨云的自助服务能力
- 对node工程进行压力测试与性能分析
- 【解决】RESP.app 连接不上redis
- Polar Parametrization for Vision-based Surround-View 3D Detection Paper Notes
- TikTok平台的两种账户有什么区别?
- Introduction to coredns
- A list of 300+ learning resources compiled by senior engineers of the Tao Department (the latest version in 2021)
猜你喜欢
直播系统聊天技术(八):vivo直播系统中IM消息模块的架构实践
Automated operation and maintenance tools - ansible, overview, installation, module introduction
淘系资深工程师整理的300+项学习资源清单(2021最新版)
Different ways of shell scripting
pytorch basic operations: classification tasks using neural networks
Integrate ssm (1)
使用TinkerPop框架对GDB增删改查
Redis-cluster mode (master-slave replication mode, sentinel mode, clustering mode)
金山云团队分享 | 5000字读懂Presto如何与Alluxio搭配
The virtual reality real estate display system foresees the future decoration effect in advance
随机推荐
关于鸿蒙系统 JS UI 框架源码的分析
Differences between i++ and ++i in loops in C language
21 Day Learning Challenge Schedule
kubernetes affinity, anti-affinity, taint, tolerance
Redis-----非关系数据库
物联网如何改变城市运行效率
Integrate ssm (1)
构造方法、成员变量、局部变量
What are the ways to improve software testing capabilities?After reading this article, it will take you up a notch
腾讯大咖分享 | 腾讯Alluxio(DOP)在金融场景的落地与优化实践
Redis-cluster mode (master-slave replication mode, sentinel mode, clustering mode)
There are more and more talents in software testing. Why are people still reluctant to take the road of software testing?
pytorch basic operations: classification tasks using neural networks
网安学习-内网渗透4
An advanced method for solving palindromes
zabbix自动发现和自动注册
人工神经网络
Guarantee WIFI security in home and enterprise-with AC and AP networking experiment
MarkDown公式指导手册
触发器简单解释