【问题标题】:Scala Slick doesn't read or write H2 databaseScala Slick 不读取或写入 H2 数据库
【发布时间】:2018-08-05 16:39:08
【问题描述】:

我为 OSX 安装了 H2,我可以通过打开 jar 文件来打开控制台。 我遵循了 Slick 的 getting started instructions 并最终得到了以下最终代码:

package com.abc.xyz

import slick.driver.H2Driver.api._
import scala.concurrent.ExecutionContext.Implicits.global

object TestSlick extends App {
  val db = Database.forConfig("h2mem1")
  try {
    // Definition of the SUPPLIERS table
    class Suppliers(tag: Tag) extends Table[(Int, String, String, String, String, String)](tag, "SUPPLIERS") {
      def id = column[Int]("SUP_ID", O.PrimaryKey) // This is the primary key column
      def name = column[String]("SUP_NAME")
      def street = column[String]("STREET")
      def city = column[String]("CITY")
      def state = column[String]("STATE")
      def zip = column[String]("ZIP")
      // Every table needs a * projection with the same type as the table's type parameter
      def * = (id, name, street, city, state, zip)
    }
    val suppliers = TableQuery[Suppliers]

    // Definition of the COFFEES table
    class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {
      def name = column[String]("COF_NAME", O.PrimaryKey)
      def supID = column[Int]("SUP_ID")
      def price = column[Double]("PRICE")
      def sales = column[Int]("SALES")
      def total = column[Int]("TOTAL")
      def * = (name, supID, price, sales, total)
      // A reified foreign key relation that can be navigated to create a join
      def supplier = foreignKey("SUP_FK", supID, suppliers)(_.id)
    }
    val coffees = TableQuery[Coffees]

    val setup = DBIO.seq(
      // Create the tables, including primary and foreign keys
      (suppliers.schema ++ coffees.schema).create,

      // Insert some suppliers
      suppliers += (101, "Acme, Inc.",      "99 Market Street", "Groundsville", "CA", "95199"),
      suppliers += ( 49, "Superior Coffee", "1 Party Place",    "Mendocino",    "CA", "95460"),
      suppliers += (150, "The High Ground", "100 Coffee Lane",  "Meadows",      "CA", "93966"),
      // Equivalent SQL code:
      // insert into SUPPLIERS(SUP_ID, SUP_NAME, STREET, CITY, STATE, ZIP) values (?,?,?,?,?,?)

      // Insert some coffees (using JDBC's batch insert feature, if supported by the DB)
      coffees ++= Seq(
        ("Colombian",         101, 7.99, 0, 0),
        ("French_Roast",       49, 8.99, 0, 0),
        ("Espresso",          150, 9.99, 0, 0),
        ("Colombian_Decaf",   101, 8.99, 0, 0),
        ("French_Roast_Decaf", 49, 9.99, 0, 0)
      )
      // Equivalent SQL code:
      // insert into COFFEES(COF_NAME, SUP_ID, PRICE, SALES, TOTAL) values (?,?,?,?,?)
    )

    val setupFuture = db.run(setup)

    println("Coffees:")
    db.run(coffees.result).map(_.foreach {
      case (name, supID, price, sales, total) =>
        println("  " + name + "\t" + supID + "\t" + price + "\t" + sales + "\t" + total)
    })
  } finally db.close
}

在 application.conf 中,我有以下条目:

h2mem1 = {
  url = "jdbc:h2:~/test"
  driver = org.h2.Driver
  connectionPool = disabled
  keepAliveConnection = true
  DB_CLOSE_DELAY=-1
}

程序运行时没有警告或错误,但未列出插入的咖啡。它只显示字符串“Coffees:”并以退出代码 0 退出。用 H2 控制台检查我发现给定的数据库确实是空的,因此插入数据不起作用。

由于没有警告或错误,我不知道从哪里开始。 H2 数据库设置有问题吗?我怎样才能知道?

【问题讨论】:

    标签: scala h2 slick


    【解决方案1】:

    您上面的代码的问题是db.run(setup) 返回一个未来,您只能在该未来完成时查询您的表。如果您在db.run(setup) 返回的future 完成之前尝试查询,则数据库中将没有数据。所以把你的代码改成

    val query = for {
      r <- coffees
    } yield (r.name, r.supID, r.price, r.sales, r.total)
    val future = for {
      _ <- db.run(setup)
      r <- db.run(query.result)
    } yield r
    val rows = Await.result(future, Duration.Inf)
    rows.foreach{ row =>
       println(row)
    }
    

    在上面的代码中。我只在 db.run(setup) 未来完成后才执行查询。

    查询的返回值也是一个未来,所以我需要添加一个等待调用以确保所有结果都已返回,然后才尝试打印结果。

    【讨论】:

      【解决方案2】:

      注意db.run(dbio) 返回Future。所以你的代码的作用是:

      • 运行设置未来
      • 无需等待设置结束即可打印
      • 运行获取所有结果 Future 而无需等待设置结束
      • 关闭连接,无需等待任何期货

      我对没有错误感到惊讶,但也许这一切都意外地完成了,没有在查询中间终止连接。

      但是为了让它更可预测(并且做你想做的事)

      (for {
        _ <- db.run(setup)
        _ = println("Coffees:")
        _ <- db.run(coffees.result).map(_.foreach {
          case (name, supID, price, sales, total) =>
            println("  " + name + "\t" + supID + "\t" + price + "\t" + sales + "\t" + total)
          }
        )
      } ()).onComplete { _ => db.close }
      

      【讨论】:

        【解决方案3】:

        感谢其他人的回答。事实上,应该与期货合作以确保它完成。然而,在我的情况下,它变成了另一个问题。

        仅在从application.conf 文件中删除connectionPool=disabled 行后,编译器才告诉我找不到驱动程序org.h2.Driver。我不得不添加

        libraryDependencies += "com.h2database" % "h2" % "1.4.196"
        

        到我的 sbt 文件。

        【讨论】:

          猜你喜欢
          • 2016-02-12
          • 2012-12-10
          • 1970-01-01
          • 1970-01-01
          • 2013-11-05
          • 1970-01-01
          • 2014-07-22
          • 2018-06-14
          • 2011-02-17
          相关资源
          最近更新 更多