Scala Slick 如何将Scala 代码翻译成JDBC? [英] How does Scala Slick translate Scala code into JDBC?

查看:56
本文介绍了Scala Slick 如何将Scala 代码翻译成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:

  1. Scala 的 for 理解语法,转换为方法调用.Slick 中定义的表是 Monads - 它们具有神奇的 foreachmapflatMapfilter 方法允许它们在 for 'loops' 中表达,而 Scala将它们转换为方法调用(如代码中正确说明的那样)由 @emil-ivanov 的另一个答案 提供).

  1. Scala's for comprehension syntax, which is translated to method calls. Tables defined in Slick are Monads - they have the magic foreach, map, flatMap, and filter methods which allow them to be expressed in for '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/mapfilter 的方法调用;不同于常规系列,mapfilter 的 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)

所以 q2type 不是你通常的集合(作为 Scala 中的理解通常用于返回),而是查询的表示.(正如 Scala Option Monad 也适用于 for 理解尽管不是集合"(就像 ListMap 那样))

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.< 方法不做 < 通常做的事情(在普通 Ints 的情况下) - 它只是返回对应于 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 Ints) - 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆