Getting autoincrement values with Slick library in Scala

时光总嘲笑我的痴心妄想 提交于 2019-12-20 09:37:23

问题


How do I get the auto-incremented values for records inserted with Slick? The following code prints 1111. I would have expected it to print 1234

import scala.slick.driver.H2Driver.simple._

object TestMappedTable extends App{
    case class User(id: Option[Int], first: String, last: String)

    object Users extends Table[User]("users") {
        def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
        def first = column[String]("first")
        def last = column[String]("last")
        def * = id.? ~ first ~ last <> (User, User.unapply _)
    }

  implicit val session = Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver").createSession()
  session.withTransaction{
    Users.ddl.create

    print(Users.insert(User(None, "Jack", "Green" )))
    print(Users.insert(User(None, "Joe", "Blue" )))
    print(Users.insert(User(None, "John", "Purple" )))
    print(Users.insert(User(None, "Jim", "Yellow" )))
  }
}

I'm using Slick 0.11.2 for Scala 2.10.0-RC1


回答1:


You can retrieve the generated value like this.

Add autoInc method to Users object.

def autoInc = id.? ~ first ~ last <> (User, User.unapply _) returning id

Use Users.autoInc.insert instead.

print(Users.autoInc.insert(User(None, "Jack", "Green" )))

See also:

https://github.com/slick/slick/issues/10

https://github.com/slick/slick/commit/09a65a8e88a0363412e218dc5c06023b69809649




回答2:


The latest version of Slick (2.1.0) automatically takes care of ignoring the auto-incremented ids and the documentation demonstrates how to retrieve the id:

val userWithId =
  (users returning users.map(_.id)
         into ((user,id) => user.copy(id=Some(id)))
  ) += User(None, "Stefan", "Zeiger")

This is the full monty, where the retrieved value is then inserted back into the object you are adding to the table. If you just want to get your hands on the id itself:

val userId =
  (users returning users.map(_.id)) += User(None, "Stefan", "Zeiger")

Both code snippets were taken from the official docs. It seemed like this question needed updating for newcomers (like me) who have never used earlier versions of Slick.




回答3:


According to SLICK Inserting document, you should define a method forInsert looks like:

def forInsert = first ~ last <> (
    { t =>
        User(None, t._1, t._2)},
    { (u: User) =>
        Some((u.first, u.last))
    }) returning id

To get result:

def save(user: User): User = {
    val id = users.forInsert.insert(user)
    new User(Some(id), user.first, user.last)
}



回答4:


For me, following source worked (Slick 3.0.2)

class Track(tag: Tag)
   extends Table[(Int, String, String)](tag, "TRACK") {
   // This is the primary key column:
   def id: Rep[Int] = column[Int]("ID", O.PrimaryKey, O.AutoInc)
   def artist: Rep[String] = column[String]("ARTIST")
   def name: Rep[String] = column[String]("NAME")

   def * : ProvenShape[(Int, String, String)] =
     (id, artist, name)
}


来源:https://stackoverflow.com/questions/13114255/getting-autoincrement-values-with-slick-library-in-scala

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!