运行 当前版本的 slick-codegen-example

run slick-codegen-example with current versions

我目前正在迈出使用 Slick 的第一步。我对 codegen 特别感兴趣。首先,我安装了 Typesafe Activator (activator-dist-1.3.7),启动了 Activator ui,从模板 "Using Slicks default code generator" (slick-codegen-example) 创建了一个新项目并启动了它。

一切顺利 ui 并且确实生成了源代码。打开 Build.scala 我注意到引用的版本非常过时(例如使用 2013 年的 Scala 2.10.3)。所以我检查了哪些是当前版本并替换了

      scalaVersion := "2.10.3",
  libraryDependencies ++= List(
    "com.typesafe.slick" %% "slick" % "2.1.0",
    "com.typesafe.slick" %% "slick-codegen" % "2.1.0-RC3",
    "org.slf4j" % "slf4j-nop" % "1.6.4",
    "com.h2database" % "h2" % "1.3.170"
  ),

在 Build.scala 和

      scalaVersion := "2.11.7",
  libraryDependencies ++= List(
    "com.typesafe.slick" %% "slick" % "3.1.1",
    "com.typesafe.slick" %% "slick-codegen" % "3.1.1",
    "org.slf4j" % "slf4j-nop" % "1.7.13",
    "com.h2database" % "h2" % "1.4.190"
  ),

然后我还更新了包名(Alex:感谢您的提示!)使这个 build。我还在创建表 sql 代码中添加了 "if now exists",因为出于某种未知原因,数据库抱怨表确实已经存在。

所以 Tables.scala 终于创建了 :) 但是,运行 和 Example.scala 示例查询不输出任何内容。经过一些研究,我了解到这是因为 Slick 3 现在是异步工作的。在其他一些示例中,如果已经看到 db.run 被包裹在 Await.result 中。所以我尝试了这个,这导致了编译错误:

value groupBy is not a member of (String, String)

出了什么问题?我该如何解决?查询代码现在如下所示:

  val q = Companies.join(Computers).on(_.id === _.manufacturerId).map {
   case (co,cp) => (co.name, cp.name) }

  Await.result(db.run(q.result), Duration.Inf).foreach { result =>
    println(result.groupBy{ case (co,cp) => co }
            .mapValues(_.map{ case (co,cp) => cp })
            .mkString("\n")
          )
  }

slick 3.0 的包结构是 changed。您需要使用 slick.codegen.SourceCodeGenerator 而不是 scala.slick.codegen.SourceCodeGenerator

知道了 运行 :) 除了更改版本号(见上文)外,我还必须:

  • 从 Build.scala 中的精巧包名称中删除 "scala." 前缀(再次感谢 Alex)
  • 将create.sql中的所有"create table"改为"create table if not exists"
  • 重写Example.scala:

    object Example extends App {
      // connection info for a pre-populated throw-away, in-memory db for this demo, which is freshly initialized on every run
      val url = "jdbc:h2:mem:test;INIT=runscript from 'src/main/sql/create.sql'"
      val db = Database.forURL(url, driver = "org.h2.Driver")
    
      // Using generated code. Our Build.sbt makes sure they are generated before compilation.
      val query = Companies.join(Computers).on(_.id === _.manufacturerId).map{ case (co,cp) => (co.name, cp.name) }
      val future = db.run(query.result)
    
      future onSuccess {  
        case result => println(result.groupBy{ case (co,cp) => co }
                                     .mapValues(_.map{ case (co,cp) => cp })
                                     .mkString("\n")
                              )
      }
      future onFailure {
        case t => println("Got an error: " + t.getMessage)
      }
      Thread.sleep(1000)    
    }