【问题标题】:Slick Scala not inserting any valuesSlick Scala没有插入任何值
【发布时间】:2013-07-24 16:43:52
【问题描述】:

有点狡猾的 n00b...我正在尝试构建一个插入语句,但发现我没有插入任何东西。

def newUser(userName: String, email: Option[String], password: String = null, removed: Option[Int] = null) = SlickInit.dbMaster withSession {

  val creation = Option(new java.sql.Timestamp(new java.util.Date().getTime()))
  val last = new java.sql.Timestamp(new java.util.Date().getTime())

  printf("REACHED 1. creation: " + creation + "\n last: " + last)
  println("\nusername: " + userName + "\n email: " + email)
  println("maxId: " + maxId)

  val invoker = Users.insertInvoker

  (Users.userId ~ Users.userName ~ Users.email ~ Users.userPassword ~ Users.creationDate ~ Users.lastLoginDate ~ Users.removed).insert(maxId, userName, email, password, creation, last, removed)

  val statement = Users.insertStatement
  println("REACHED 2. \n\nStatement: " + statement)
}

在发出 POST 请求时打印 REACHED 1(带有所需值),但不是 REACHED 2。我确定我的插入语句有问题,但我不确定是什么。 (另外,很明显,当我查询数据库时,插入的值不会返回。)有人对此有任何见解吗?

编辑,这是我的用户表定义:

object Users extends Table[(Int, String, Option[String], String, Option[Timestamp], Timestamp, Option[Int])]("APUsers") {

   def userId          = column[Int]("UserId", O.PrimaryKey, O.AutoInc)
   def userName        = column[String]("UserName")
   def email           = column[Option[String]]("Email", O.Nullable)
   def userPassword    = column[String]("UserPassword")
   def creationDate    = column[Option[Timestamp]]("CreationDate", O.Nullable)
   def lastLoginDate   = column[Timestamp]("LastLoginDate")
   def removed         = column[Option[Int]]("removed", O.Nullable)

   def * = userId ~ userName ~ email ~ userPassword ~ creationDate ~ lastLoginDate ~ removed
 }

【问题讨论】:

  • 你能发布用户对象定义吗?
  • 是否看到任何异常被抛出?你在使用内存数据库吗?

标签: scala slick scalatra


【解决方案1】:

在用户对象定义中,您需要更改:

object Users extends Table[(Int, String, Option[String], String, Option[Timestamp], Timestamp, Option[Int])]("APUsers") {

到这里:

object Users extends Table[(Option[Int], String, Option[String], String, Option[Timestamp], Timestamp, Option[Int])]("APUsers") {

因为id 是由 DBMS (O.AutoInc) 分配的。请参阅此处的示例:http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#mapped-tables

那么你需要改变这个:

def * = userId ~ userName ~ email ~ userPassword ~ creationDate ~
        lastLoginDate ~ removed

到这里:

def * = userId.? ~ userName ~ email.? ~ userPassword ~ creationDate.? ~
        lastLoginDate ~ removed.?

因为它们被定义为Option。见这里:http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#mapped-tables

newUser 中,插入行应该是这样的:

(Users.userId ~ Users.userName ~ Users.email ~ Users.userPassword ~
 Users.creationDate ~ Users.lastLoginDate ~ Users.removed)

(Users.userName ~ Users.email.? ~ Users.userPassword ~ Users.creationDate.? ~ 
 Users.lastLoginDate ~ Users.removed.?)
 .insert(userName, email, password, creation, last, removed)

没有userId,因为它将由 DBMS 分配。请参阅此处的示例:http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#inserting

由于您不接受数据库中的 Null,我建议更改此设置:

def newUser(userName: String, email: Option[String], password: String = null, removed: Option[Int] = null)

到这里:

def newUser(userName: String, email: Option[String], password: String, removed: Option[Int] = null)

并检查密码是否为空。

根据 pedrofurla 的建议,您可以将以下内容添加到 Users 对象:

def forInsert = Users.userName ~ Users.email.? ~ Users.userPassword ~ 
                Users.creationDate.? ~ Users.lastLoginDate ~ Users.removed.?

并使该行更具可读性:

Users.forInsert.insert(userName, email, password, creation, last, removed)

http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#inserting

【讨论】:

  • 感谢大卫的建议。不幸的是,Eclipse 抛出错误:- too many arguments for method insert: (value: (Int, String, Option[Option[String]], String, Option[Option[java.sql.Timestamp]], java.sql.Timestamp, Option[Option[Int]]))(implicit session: scala.slick.session.Session)Int
  • 我建议使用投影*Users.*.insert...
  • @pedrofurla 我将您的建议添加到答案中。
  • 哦,对了,我忘了PK。我通常会制作另一个包含插入字段的投影。
  • 是的,我也这样做:-) 代表以下While some database systems allow inserting proper values into AutoInc columns or inserting None to get a created value, most databases forbid this behaviour, so you have to make sure to omit these columns. Slick does not yet have a feature to do this automatically but it is planned for a future release. For now, you have to use a projection which does not include the AutoInc column删除:slick.typesafe.com/doc/1.0.1/lifted-embedding.html#inserting
猜你喜欢
  • 2018-02-17
  • 1970-01-01
  • 2015-10-23
  • 2016-07-30
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多