0

我目前正在使用 Slick 迈出第一步。我对代码生成特别感兴趣。首先,我安装了 Typesafe Activator (activator-dist-1.3.7),启动了 Activator ui,从模板“使用 Slicks 默认代码生成器”(slick-codegen-example) 创建了一个新项目并启动它。

进展顺利,确实生成了源代码。打开 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:感谢您的提示!)以进行此构建。我还在创建表 sql 代码中添加了“如果现在存在”,因为由于某种未知原因,数据库抱怨表确实已经存在。

所以最终创建了 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")
          )
  }
4

2 回答 2

0

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

于 2015-12-17T08:17:52.647 回答
0

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

  • 删除“scala”。Build.scala 中光滑包名称的前缀(再次感谢 Alex)
  • 在 create.sql 中将所有“创建表”更改为“如果不存在则创建表”
  • 重写 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)    
    }
    
于 2015-12-18T08:02:20.343 回答