jooq
每个框架都会引入新的折衷方案。 引入折衷方案是因为该框架对您希望如何与软件基础结构进行交互做出了一些假设。
最近,这种折衷触及用户的例子是“ Slick查询是否通常与SQL查询同构? ”。 而且,答案当然是:否。这似乎是一个简单的Slick查询:
val salesJoin = sales
join purchasers
join products
join suppliers on {
case (((sale, purchaser), product), supplier) =>
sale.productId === product.id &&
sale.purchaserId === purchaser.id &&
product.supplierId === supplier.id
}
…变成了一个很大的怪物,带有大量的派生表,鉴于原始查询(格式是我的),这是完全不必要的:
select x2.x3, x4.x5, x2.x6, x2.x7
from (
select x8.x9 as x10,
x8.x11 as x12,
x8.x13 as x14,
x8.x15 as x7,
x8.x16 as x17,
x8.x18 as x3,
x8.x19 as x20,
x21.x22 as x23,
x21.x24 as x25,
x21.x26 as x6
from (
select x27.x28 as x9,
x27.x29 as x11,
x27.x30 as x13,
x27.x31 as x15,
x32.x33 as x16,
x32.x34 as x18,
x32.x35 as x19
from (
select x36."id" as x28,
x36."purchaser_id" as x29,
x36."product_id" as x30,
x36."total" as x31
from "sale" x36
) x27
inner join (
select x37."id" as x33,
x37."name" as x34,
x37."address" as x35
from "purchaser" x37
) x32
on 1=1
) x8
inner join (
select x38."id" as x22,
x38."supplier_id" as x24,
x38."name" as x26
from "product" x38
) x21
on 1=1
) x2
inner join (
select x39."id" as x40,
x39."name" as x5,
x39."address" as x41
from "supplier" x39
) x4
on ((x2.x14 = x2.x23)
and (x2.x12 = x2.x17))
and (x2.x25 = x4.x40)
where x2.x7 >= ?
前Slick维护者Christopher Vogt仍积极参与Slick社区成员,他用以下话解释了上述内容:
这意味着Slick依靠数据库的查询优化器来执行Slick有效产生的sql查询。 目前,在MySQL中并非总是如此
根据Christopher所说,Slick背后的主要思想之一是:
Slick不是允许您构建完全指定SQL字符串的DSL。 Slick的Scala查询翻译允许重复使用和编写,并使用Scala作为编写查询的语言。 它不允许您仅通过语义和粗略结构来预测确切的sql查询。
光滑vs.jOOQ
由于Christopher后来也将Slick与jOOQ进行了比较,因此我允许自己发出声音并加上两分钱:
从较高的水平(没有实际的Slick经验),我会说Slick和jOOQ都很好地接受了合成。 我已经看到在客户代码中疯狂地查询了数百行[jOOQ] SQL,这些查询是由几种方法组成的。 您可以使用两个API来做到这一点。
另一方面,正如克里斯所说:Slick专注于Scala集合,jOOQ专注于SQL表。
- 从概念的角度(从理论上讲),此重点无关紧要。
- 从类型安全的角度来看,Scala集合比SQL表和查询更容易进行类型检查,因为考虑到各种高级SQL子句的语义相当隐式地更改了类型配置,因此SQL作为一种语言本身很难进行类型检查。外部联接,分组集,枢纽子句,并集,分组依据等)。
- 从实践的角度来看,SQL本身只是原始关系理论的近似,并且已经拥有了自己的生命。 这可能对您无关紧要。
我想最终可以归结为您是否要推理Scala集合(将查询与客户端代码更好地集成/更加习惯)或关于SQL表(将查询与您的数据库更好地集成/更加习惯) 。
在这一点上,我想在讨论中再加上两美分。 客户不购买您要销售的产品。 他们从不这样做。 对于Hibernate,客户和用户希望能够永远忘记SQL。 反之亦然。 正如加文·金本人(Hibernate的创造者)告诉我的那样:
因为客户和用户从未听过加文(以及其他ORM创建者),所以我们现在有很多人称之为对象关系阻抗不匹配 。 对Hibernate和JPA的API提出了许多不合理的批评,对于它们真正涵盖的有限范围而言,它们太受欢迎了。
对于Slick( 或C#的LINQ ),如果用户滥用这些工具以替代SQL,则类似的不匹配会阻碍集成。 Slick在直接使用Scala语言对关系模型进行建模方面做得非常出色。 如果您想推理关系就像推理集合一样,这很棒。 但这不是 SQL API。 为了说明克服这些限制有多么困难,您可以浏览问题跟踪器或用户组以了解:
我们简称为:
功能关系阻抗不匹配
SQL更多
Markus Winand(流行的SQL Performance Explained的作者)最近发表了一篇关于“现代SQL”的很好的演讲,我们在jOOQ完全赞同这一想法:
我们认为,试图从通用语言(如Java,Scala和C#)中隐藏SQL语言的API缺少许多非常不错的功能,这些功能可以为您的应用程序增加巨大的价值。 jOOQ是一个完全包含SQL语言的API,具有其所有出色的功能(及其所有怪癖)。 您显然可能同意也可能不同意。
我们将使本文处于开放式状态,希望您能喜欢上讨论每种方法的好处和注意事项。 接近Scala与接近SQL。
但是,作为一个小型预告片,我想宣布一篇后续文章,该文章显示不存在对象关系阻抗不匹配的情况。 您(和您的ORM)只是没有正确使用SQL。 敬请关注!
翻译自: https://www.javacodegeeks.com/2015/03/jooq-vs-slick-pros-and-cons-of-each-approach.html
jooq