Подтвердить что ты не робот

Получение значений автоинкремента с библиотекой Slick в Scala

Как получить автоматически увеличивающиеся значения для записей, вставленных с помощью Slick? Следующий код печатает 1111. Я бы ожидал, что он напечатает 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" )))
  }
}

Я использую Slick 0.11.2 для Scala 2.10.0-RC1

4b9b3361

Ответ 1

Вы можете получить сгенерированное значение, подобное этому.

Добавьте autoInc метод к объекту Users.

def autoInc = id.? ~ first ~ last < > (User, User.unapply _) возвращение id

Используйте Users.autoInc.insert вместо этого.

print (Users.autoInc.insert(Пользователь (Нет, "Джек", "Зеленый" )))

См. также:

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

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

Ответ 2

Последняя версия Slick (2.1.0) автоматически заботится о игнорировании автоинкрементных идентификаторов, и в документации показано, как получить идентификатор:

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

Это полный monty, где восстановленное значение затем вставляется обратно в объект, который вы добавляете в таблицу. Если вы просто хотите получить доступ к самому идентификатору:

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

Оба фрагмента кода были взяты из официальных документов. Казалось, что этот вопрос нуждается в обновлении для новичков (таких как я), которые никогда не использовали более ранние версии Slick.

Ответ 3

Согласно SLICK Вставляя документ, вы должны определить метод forInsert, который выглядит следующим образом:

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

Чтобы получить результат:

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

Ответ 4

Для меня, следующий источник работал (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)
}