无法使用 Play for Scala 和 Anorm 从表单中插入值
Cannot insert values from form using Play for Scala and Anorm
当我在表单字段中输入数据并单击 "Add book" 按钮时,没有任何反应...输入到字段中的数据并没有添加到数据库中,我没有收到任何错误,我也不知道我做错了什么...
我有以下控制器
package controllers
import play.api.data.Form
import play.api.data.Forms._
import play.api.mvc.{Action, Controller}
import anorm.NotAssigned
import play.api.Play.current
import play.api.i18n.Messages.Implicits._
import models.Buch
object Book extends Controller{
val addBookForm = Form(
mapping(
"name" -> nonEmptyText,
"author" -> nonEmptyText,
"category" -> nonEmptyText,
"read" -> boolean,
"amount" -> number
)(Buch.apply)(Buch.unapply)
)
def add = Action {
Ok(views.html.book(addBookForm))
}
def addBuch() = Action { implicit request =>
addBookForm.bindFromRequest.fold(
errors => BadRequest,
{
case Buch(name, author, category, read, amount) =>
Buch.addBook(Buch(name, author, category, read, amount))
Ok("Book successfully added!")
}
)
}
}
以下型号
package models
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
case class Buch(name:String, author:String, category:String, read:Boolean, amount: Int)
object Buch{
val simple = {
get[String]("buch.name") ~
get[String]("buch.auhtor") ~
get[String]("buch.category") ~
get[Boolean]("buch.read") ~
get[Int]("buch.amount") map {
case name~author~category~read~amount => Buch(name, author, category, read, amount)
}
}
def findAll(): Seq[Buch] = {
DB.withConnection { implicit connection =>
SQL("select * from buch").as(Buch.simple *)
}
}
def addBook(buch:Buch): Unit = {
DB.withConnection { implicit connection =>
SQL("insert into buch(name, author, category, read, amount) values ({name}, {author}, {category}, {read}, {amount})").on(
'name -> buch.name,
'author -> buch.author,
'category -> buch.category,
'read -> buch.read,
'amount -> buch.amount
).executeUpdate()
}
}
}
以下sql脚本
# Buch schema
# --- !Ups
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
# --- !Downs
DROP TABLE Buch;
以下观点
@(form: Form[Buch])(implicit messages: Messages)
@main("Welcome to Play 2.0") {
@helper.form(action = routes.Book.addBuch) {
@helper.inputText(form("name"))
@helper.inputText(form("author"))
@helper.inputText(form("category"))
@helper.inputText(form("read"))
@helper.inputText(form("amount"))
<input type="submit" value="Add book"/>
}
}
如果我修改模型,例如仅使用 3 个参数创建它,名称、作者和类别,方法 addBook 会将数据插入我的数据库。
谁能告诉我我做错了什么?
谢谢!
在mysql中,read
是保留字。参见 docs。
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
你应该用一些非保留词替换它(例如 book_read)或者通过像这样放入反引号来转义它:
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
`read` boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
编辑:
Anorm 不提供从 mysql 布尔值到 scala 布尔值的默认映射。从它的 documentation:
It’s possible to add custom mapping, for example if underlying DB
doesn’t support boolean datatype and returns integer instead. To do
so, you have to provide a new implicit conversion for Column[T], where
T is the target Scala type:
import anorm.Column
// Custom conversion from JDBC column to Boolean
implicit def columnToBoolean: Column[Boolean] =
Column.nonNull1 { (value, meta) =>
val MetaDataItem(qualified, nullable, clazz) = meta
value match {
case bool: Boolean => Right(bool) // Provided-default case
case bit: Int => Right(bit == 1) // Custom conversion
case _ =>
Left(TypeDoesNotMatch(s"Cannot convert $value: ${value.asInstanceOf[AnyRef].getClass} to Boolean
for column $qualified"))
}
}
另请参阅 this discussion 关于 Anorm - Mysql 布尔值。
当我在表单字段中输入数据并单击 "Add book" 按钮时,没有任何反应...输入到字段中的数据并没有添加到数据库中,我没有收到任何错误,我也不知道我做错了什么...
我有以下控制器
package controllers
import play.api.data.Form
import play.api.data.Forms._
import play.api.mvc.{Action, Controller}
import anorm.NotAssigned
import play.api.Play.current
import play.api.i18n.Messages.Implicits._
import models.Buch
object Book extends Controller{
val addBookForm = Form(
mapping(
"name" -> nonEmptyText,
"author" -> nonEmptyText,
"category" -> nonEmptyText,
"read" -> boolean,
"amount" -> number
)(Buch.apply)(Buch.unapply)
)
def add = Action {
Ok(views.html.book(addBookForm))
}
def addBuch() = Action { implicit request =>
addBookForm.bindFromRequest.fold(
errors => BadRequest,
{
case Buch(name, author, category, read, amount) =>
Buch.addBook(Buch(name, author, category, read, amount))
Ok("Book successfully added!")
}
)
}
}
以下型号
package models
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
case class Buch(name:String, author:String, category:String, read:Boolean, amount: Int)
object Buch{
val simple = {
get[String]("buch.name") ~
get[String]("buch.auhtor") ~
get[String]("buch.category") ~
get[Boolean]("buch.read") ~
get[Int]("buch.amount") map {
case name~author~category~read~amount => Buch(name, author, category, read, amount)
}
}
def findAll(): Seq[Buch] = {
DB.withConnection { implicit connection =>
SQL("select * from buch").as(Buch.simple *)
}
}
def addBook(buch:Buch): Unit = {
DB.withConnection { implicit connection =>
SQL("insert into buch(name, author, category, read, amount) values ({name}, {author}, {category}, {read}, {amount})").on(
'name -> buch.name,
'author -> buch.author,
'category -> buch.category,
'read -> buch.read,
'amount -> buch.amount
).executeUpdate()
}
}
}
以下sql脚本
# Buch schema
# --- !Ups
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
# --- !Downs
DROP TABLE Buch;
以下观点
@(form: Form[Buch])(implicit messages: Messages)
@main("Welcome to Play 2.0") {
@helper.form(action = routes.Book.addBuch) {
@helper.inputText(form("name"))
@helper.inputText(form("author"))
@helper.inputText(form("category"))
@helper.inputText(form("read"))
@helper.inputText(form("amount"))
<input type="submit" value="Add book"/>
}
}
如果我修改模型,例如仅使用 3 个参数创建它,名称、作者和类别,方法 addBook 会将数据插入我的数据库。
谁能告诉我我做错了什么?
谢谢!
在mysql中,read
是保留字。参见 docs。
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
你应该用一些非保留词替换它(例如 book_read)或者通过像这样放入反引号来转义它:
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
`read` boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
编辑:
Anorm 不提供从 mysql 布尔值到 scala 布尔值的默认映射。从它的 documentation:
It’s possible to add custom mapping, for example if underlying DB doesn’t support boolean datatype and returns integer instead. To do so, you have to provide a new implicit conversion for Column[T], where T is the target Scala type:
import anorm.Column // Custom conversion from JDBC column to Boolean implicit def columnToBoolean: Column[Boolean] = Column.nonNull1 { (value, meta) => val MetaDataItem(qualified, nullable, clazz) = meta value match { case bool: Boolean => Right(bool) // Provided-default case case bit: Int => Right(bit == 1) // Custom conversion case _ => Left(TypeDoesNotMatch(s"Cannot convert $value: ${value.asInstanceOf[AnyRef].getClass} to Boolean for column $qualified")) } }
另请参阅 this discussion 关于 Anorm - Mysql 布尔值。