Scala Slick 值 foreach 不是

Scala Slick value foreach is not a member of

这是一个用于连接到 MariaDB 的 Scala Play 项目。

cat build.sbt
...
jdbc,
"org.mariadb.jdbc" % "mariadb-java-client" % "2.6.2",
"com.typesafe.slick" %% "slick" % "3.3.2",
...
class Users(tag: Tag) extends Table[(...)](tag, "USERS") {...}

val users = TableQuery[Users]

for (u <- users) {...}

错误:

value foreach is not a member of slick.lifted.TableQuery[controller.Users]

for (u <- users) {
          ^

我尝试在 for 循环中将 .result 添加到 users,但我得到了

value foreach is not a member of slick.jdbc.MySQLProfile.StreamingProfileAction[Seq[controller.Users#TableElementType],controller.Users#TableElementType,slick.dbio.Effect.Read]

for (u <- users.result) {
                ^

我在代码中没有任何地方 db.run

您似乎想遍历数据库中的用户。

您需要了解几个概念:

  • 表达式users是一种查询。 mapfilter 等方法是生成替代查询的一种方式。使用 foreach 遍历 查询 并没有真正意义。

  • 使用 users.results 你有一个动作(一种 DBIOAction)。这是您可以发送到数据库的内容,带有 db.run。同样,像 mapflatMap 这样的方法是一种转换和组合动作的方法,但是用 foreach 迭代 一个动作 并不是真的有道理。

那怎么办? users.result 的签名类似于 DBIO[Seq[User]]。如果你想对每个用户做一些事情,也许打印出来,你可以构建一个动作来做到这一点。一种方法是 map 操作的结果(用户列表)到其他东西。也许:

val doSomethingWithEachUser: DBIO[Unit] = 
  users.result.map { seqUsers => 
    seqUsers.foreach(println)
  }

此处我们使用 mapDBIO[Seq[User]] 的结果类型更改为 DBIO[Unit]

然后您可以使用 db.rundoSomethingWithEachUser 发送到数据库(可以这么说)。当您这样做时,您的操作是 运行,当值可用时,将发生 println

切换回for理解,可以看到我们需要构造一个新的action:

val doSomethingWithEachUser: DBIO[Unit] =
  for {
    allUsers <- messages.result
  } yield allUsers.foreach(println)

...例如。

下一层将在 Future,这是 db.run 的结果。您还可以在未来使用 map (或类似的)来处理数据。 Slick 几乎都是关于这些类型的查询、操作和(最终)期货的构建块,并使用 mapflatMap.

等组合器来操纵它们