使用Anorm和Scala Play框架的动态SQL参数
是否可以为anorm的“on”方法动态创建列表 我有一个带有可选输入的表单,目前我检查每个选项,创建一个包含已定义选项的列表,并尝试将此传递给anorm。目前我得到这个编译错误使用Anorm和Scala Play框架的动态SQL参数,sql,scala,playframework,playframework-2.0,anorm,Sql,Scala,Playframework,Playframework 2.0,Anorm,是否可以为anorm的“on”方法动态创建列表 我有一个带有可选输入的表单,目前我检查每个选项,创建一个包含已定义选项的列表,并尝试将此传递给anorm。目前我得到这个编译错误 type mismatch; found : List[java.io.Serializable] required: (Any, anorm.ParameterValue[_]) 我不确定如何创建此列表。 当前代码: val onList = List( 'school_id = input.scho
type mismatch; found : List[java.io.Serializable] required: (Any, anorm.ParameterValue[_])
我不确定如何创建此列表。
当前代码:
val onList = List(
'school_id = input.school,
if(input.rooms isDefined) ('rooms -> input.rooms) else "None" ,
if(input.bathrooms isDefined) ('bathrooms -> input.bathrooms) else "None" ,
if(input.houseType isDefined) ('houseType -> input.houseType) else "None" ,
if(input.priceLow isDefined) ('priceLow -> input.priceLow) else "None" ,
if(input.priceHigh isDefined) ('priceHigh -> input.priceHigh) else "None" ,
if(input.utilities isDefined) ('utilities -> input.utilities) else "None"
).filter(_!="None")
SQL("SELECT * FROM Houses WHERE " + whereString).on(onList).as(sqlToHouse *)
我尝试过这样做,因为最初我认为它与
.on('rooms -> input.rooms, 'bathroom -> input.bathrooms... etc)
编辑:
代码现在是:
val onList = Seq(
('school_id -> input.school),
if(input.rooms isDefined) ('rooms -> input.rooms.get) else None ,
if(input.bathrooms isDefined) ('bathrooms -> input.bathrooms.get) else None ,
if(input.houseType isDefined) ('houseType -> input.houseType.get) else None ,
if(input.priceLow isDefined) ('priceLow -> input.priceLow.get) else None ,
if(input.priceHigh isDefined) ('priceHigh -> input.priceHigh.get) else None ,
if(input.utilities isDefined) ('utilities -> input.utilities.get) else None
).filter(_!=None).asInstanceOf[Seq[(Any,anorm.ParameterValue[_])]]
使用SQL命令:
SQL("SELECT * FROM Houses WHERE " + whereString).on(onList:_*).as(sqlToHouse *)
现在是例外
[ClassCastException: java.lang.Integer cannot be cast to anorm.ParameterValue]
所以我只打了几次电话
var query = SQL("SELECT * FROM Houses WHERE " + whereString).on('school_id -> input.school)
if(input.rooms isDefined) query= query.on('rooms -> input.rooms.get)
if(input.bathrooms isDefined) query= query.on('bathrooms -> input.bathrooms.get)
if(input.houseType isDefined) query= query.on('houseType -> input.houseType.get)
if(input.priceLow isDefined) query= query.on('priceLow -> input.priceLow.get)
if(input.priceHigh isDefined) query= query.on('priceHigh -> input.priceHigh.get)
if(input.utilities isDefined) query= query.on('utilities -> input.utilities.get)
query.as(sqlToHouse *)
重要的是,您必须创建
ParameterValue
类型的值。
这通常使用TopParameterValue()
函数完成
一种方法是创建一系列可展平的选项:
val onList = Seq(
Some('school_id -> input.school),
input.rooms.map('rooms -> _),
input.bathrooms.map('bathrooms -> _)
).flatten
然后可以将此序列映射到正确的值:
SQL(
"SELECT * FROM Houses WHERE " + whereString
).on(
onList.map(v => v._1 -> toParameterValue(v._2)): _*
)
这可以简化如下:
val onList = Seq(
Some('school_id -> input.school),
input.rooms.map('rooms -> _),
input.bathrooms.map('bathrooms -> _)
).flatMap(_.map(v => v._1 -> toParameterValue(v._2)))
SQL(
"SELECT * FROM Houses WHERE " + whereString
).on(
onList: _*
)
或者最简单的解决方案是:
val onList = Seq(
Some('school_id -> toParameterValue(input.school)),
input.rooms.map('rooms -> toParameterValue(_)),
input.bathrooms.map('bathrooms -> toParameterValue(_))
).flatten
SQL(
"SELECT * FROM Houses WHERE " + whereString
).on(
onList: _*
)
您可以看看多值参数是下一个Anorm(即将播放2.3/master)。太棒了!我不知道TopParameterValue函数。谢天谢地,这能行吗?
whereString
看起来像什么?