2

当我遵循 ScalaQuery 的查询教程时,我发现了一些有趣的东西,我不知道为什么。

这是我定义的数据库架构:

object Users extends Table[(Int, String, String)]("users") {
    def id = column[Int]("id", O NotNull)
    def first = column[String]("first", O NotNull)
    def last = column[String]("last", O NotNull)
    def * = id ~ first ~ last 
}

这是我使用的查询:

object Main
{
    val database = Database.forURL("jdbc:sqlite:sample.db", driver = "org.sqlite.JDBC")
    def main(args: Array[String]) {
        database withSession {

            val query1 = for (user <- Query(Users)) yield user.id ~ user.last
            val query2 = for (user <- Users if user.id > 5) yield user.id ~ user ~ last
        }
    }
}

在这种情况下,您可以在两者中看到query1query2使用类似的东西user.id,这似乎是我刚刚在上面定义user的单例类型。object Users所以它具有在该对象上定义的所有方法。

但是,如果我尝试不使用关键字直接运行查询yield,例如:

for (user <- Users if user.id > 5) {
    println ("UserID:" + user.id)
}

在这种情况下,编译器会抱怨:

[error] src/main/scala/Test.scala:23: value id is not a member of (Int, String, String)
[error]    println ("UserID:" + user.id)

在 println 语句中似乎user是 Tuple3 的类型。如果我user像下面这样使用普通的元组,它会起作用。

for (user <- Users if user.id > 5) {
    println ("UserID:" + user._1)
}

你可以看到,在 for 表达式的守卫中我仍然使用user.id,那么 的类型是user什么?为什么我可以user.id在guard和yield块中使用,但我需要将它用作表达式主体中的元组?

谢谢。

4

1 回答 1

7

在第一个代码片段中:

val query1 = for (user <- Query(Users)) yield user.id ~ user.last

userobject Users因为 Query 的 map 方法定义为def map[F](f: E => F): Query[F],所以第一个代码片段等于:

Query(Users).map(user => user.id ~ user.last)

所以EisUsers的类型和Users实例是给的参数f(E):F

如果要将行作为对象访问,则需要定义用户如下:

import org.scalaquery.ql.basic.{BasicTable => Table}
object Users extends Table[User]("users") {
  def id = column[Int]("id", O NotNull)
  def first = column[String]("first", O NotNull)
  def last = column[String]("last", O NotNull)
  def * = id ~ first ~ last <> (User, User.unapply _)
}

case class User(id: Int, first: String, last: String)

进而

for (user <- Users if user.id > 5) {
  println ("UserID:" + user.id)  // user is a User instance
}
于 2011-03-28T06:53:20.650 回答