Scala Slick 如何将Scala 代码翻译成JDBC? [英] How does Scala Slick translate Scala code into JDBC?
问题描述
Slick 如何翻译代码,例如:
How does Slick translate code such as:
val q2 = for {
c <- Coffees if c.price < 9.0
s <- Suppliers if s.id === c.supID
} yield (c.name, s.name)
for(t <- q2) println(" " + t._1 + " supplied by " + t._2)
进入JDBC?
它是否使用 Scala Virtualized?它使用其他方法吗?
Does it use Scala Virtualized? Does it use some other method?
推荐答案
Slick 的 stable API 通过它所谓的 lifted embedding 实现了这一点.您的示例显然使用了稳定的 API(因为您使用 ===
表示相等而不是 ==
).
Slick's stable API achieves this via what it calls lifted embedding. Your example is clearly using the stable API (as you use ===
for equality and not ==
).
Slick(以及 Scala)的美妙之处在于 - 在不使用宏或 Scala 虚拟化的情况下实现了这一点.(旁注:Slick 的实验性 API 确实使用了宏 - 这将允许您使用 ==
而不是 ===
或是
)
The beauty of Slick (and in turn Scala) is that - this much is achieved without using macros or Scala-Virtualized. (Side Note: Slick's experimental API does use macros - and this will allow you to use ==
instead of ===
or is
)
SQL 的翻译是通过以下方式实现的:
The translation to SQL is achieved using:
Scala 的
for
理解语法,转换为方法调用.Slick 中定义的表是 Monads - 它们具有神奇的foreach
、map
、flatMap
和filter
方法允许它们在for
'loops' 中表达,而 Scala将它们转换为方法调用(如代码中正确说明的那样)由 @emil-ivanov 的另一个答案 提供).
Scala's
for
comprehension syntax, which is translated to method calls. Tables defined in Slick are Monads - they have the magicforeach
,map
,flatMap
, andfilter
methods which allow them to be expressed infor
'loops' while Scala translates them to method calls (as correctly illustrated in the code provided by the other answer by @emil-ivanov).
与常规 Scala 集合一样,for
是嵌套的语法糖flatMap
/map
和 filter
的方法调用;不同于常规系列,map
和 filter
的 Slick Table
对象版本返回 表示查询,与每个过滤条件(if
)一起构建它或加入(如 s <- 供应商,如果 s.id 是 c.supID
)
As with regular Scala collections, the for
is syntactic sugar for nested
method calls to flatMap
/map
and filter
; unlike regular collections,
the Slick Table
objects' versions of map
and filter
return representations
of a query, building it along with every filter condition (if
) or join
(as in s <- Suppliers if s.id is c.supID
)
所以 q2
的 type 不是你通常的集合(作为 Scala 中的理解通常用于返回),而是查询的表示.(正如 Scala Option Monad 也适用于 for
理解尽管不是集合"(就像 List
或 Map
那样))
So the type of q2
is not your usual collection (as a for comprehension in Scala
is typically used to return), but rather a representation of a query.
(Just as the Scala Option Monad also works with for
comprehensions despite
not being a 'collection' (in the way that List
or Map
is))
您可以使用 q2.selectStatement
查看底层查询.
You can see the underlying query with q2.selectStatement
.
Scala 的隐式 lifting - c.price
不是 Int
而是表示一个列值 - 所以表达式 c.price <9.0
变成了 c.price.<(Const(9.0))
(一个 Int
被提升到所需的类型),而 <
只是一个方法表示 c.price
的类,一个 Column
.<
方法不做 <
通常做的事情(在普通 Int
s 的情况下) - 它只是返回对应于 price < 的 SQL AST 的表示.9
成为一部分生成并发送到 JDBC 执行的 SQL.
Scala's implicit lifting - c.price
is not an Int
but rather a representation of
a column value - so the expression c.price < 9.0
becomes c.price.<(Const(9.0))
(an Int
is lifted to the desired type), and <
is a just a method of the
class that represents c.price
, a Column
. The <
method
does not do what <
usually does (in the case of plain Int
s) - it simply returns
a representation of the SQL AST corresponding to price < 9
that becomes part of
the SQL that is generated and sent off to JDBC to execute.
在细节方面还有很多事情要做,但我认为查询 monad 和隐式提升是主要成分.
There's a whole lot else going on, in terms of details, but I think the query monad and the implicit lifting are the chief ingredients.
这篇关于Scala Slick 如何将Scala 代码翻译成JDBC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!