先简短回答。假设您在数据库中有一个包含 3 列的表:name、email、pass。但是从用户那里,你只得到了name 和password 而不是email。所以选择所有 3 个选项
val name:Option[String] = Some("alice")
val email:Option[String] = None
val pass:Option[String] = Some("password")
//For db insertion have this:
DB.withConnection { implicit conn =>
SQL("INSERT INTO USERS (name,email,pass) VALUES ({n},{e},{p})").on(
'n -> name, 'e -> email,'p -> pass).executeInsert()
}
执行上述操作,因为email 是None,它将在您的数据库中插入null。因此,在您的情况下,对于所有 10 列,您可以在上面的 SQL 语句中定义它们,并在 on() 中传递 Option。如果其中任何一个是None,那么它将在数据库中将其作为null。
虽然如果在架构中的列上存在NOT NULL 的约束,则可能会出现问题。在这种情况下,您可以将getOrElse 用于以下列:
DB.withConnection { implicit conn =>
SQL("INSERT INTO USERS (name,email,pass) VALUES ({n},{e},{p})").on(
'n -> name, 'e -> email.getOrElse("Default Email"),'p -> pass).executeInsert()
以下是关于 play 如何将类型转换为数据库类型的综合列表。它可以在对象anorm.ToStatement中找到:
case Some(bd: java.math.BigDecimal) => stmt.setBigDecimal(index, bd)
case Some(o) => stmt.setObject(index, o)
case None => stmt.setObject(index, null)
case bd: java.math.BigDecimal => stmt.setBigDecimal(index, bd)
case date: java.util.Date => stmt.setTimestamp(index, new java.sql.Timestamp(date.getTime()))
case o => stmt.setObject(index, o)
如您所见,None 将其视为 null。
如果是SELECT hmm,我不知道有什么异常特性可以在这里有所帮助,但我想简单的字符串操作可能就足够了:
def getColumns(xs:List[Option[_]]):String = {
val notNone = xs.collect{
case Some(x) => x.toString
}
notNone.mkString(",")
}
然后是SQL("SELECT %s from table".format(getColumns(List(nameColumn,emailColumn,passColumn)))。
虽然这不是你想要的。 Anorm 只是一个 sql 构建库。为了做你想做的事,它还必须记住你的表模式(即至少列名..)。我不认为 anorm 是用来做所有这些的