example code就我而言:
import slick.jdbc.MySQLProfile.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration
case class User(id: Option[Int], vid: Int, first: String, last: String)
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def vid = column[Int]("vid")
def first = column[String]("first")
def last = column[String]("last")
def * = (id.?, vid, first, last) <> (User.tupled, User.unapply)
}
val users = TableQuery[Users]
def usersForInsert = users.map(u => (u.vid, u.first, u.last).shaped <>
({t => User(None, t._1, t._2, t._3)}, {(u: User) => Some((u.vid, u.first, u.last))}))
//#insert vid value
val userWithId =
(users returning users.map(_.id)
into ((user,id) => user.copy(id=Some(id)))
//Here, I wonder how to replace the value of vid by id
) += User(None, 4, "Stefan", "Zeiger")
//#insert
val userWithIdRes = Await.result(db.run(users.schema.create >> userWithId), Duration.Inf)
println(userWithIdRes)
我已经尝试了一些方法,但是在编译和运行时总是会出错。感谢您阅读scala-slick的入门级问题
正如您定义的User.id
像AutoInc
一样,插入操作上没有值。它将由数据库系统生成。因此,您可以先插入并获取ID,然后更新所需的列。可以这样做:
val newUserId: Future[Int] =
for {
userId <- db.run(
(users returning users.map(_.id)) += User(None, 0, "Stefan", "Zeiger")
)
_ <- db.run(users.filter(_.id === userId).map(_.vid).update(userId))
} yield userId
但是,有一个额外的呼叫给DB。在将来您可能需要快速写入的情况下,这可能会导致性能问题。如果只是出于学习目的,那么它是可行的,但是在实际的代码库中,最好以其他方式进行设计。例如,vid
始终与id
具有相同的值,因此可以在应用程序级别使用vid
,但不一定在db中使用。