-->

ANORM动态过滤器(anorm dynamic filters)

2019-07-04 01:59发布

我学习了一点ANORM文档(从游戏架构),是不明确的,如果它支持常见的查询使用案例:动态过滤器,即用户填写2个或3个搜索条件的10个字段搜索表单上。

在这种情况下,我怎么能动态构造没有了传统的字符串操作查询?

Answer 1:

是的,我认为通过罗宾·格林引用的问题包含了答案。 只要定义使用占位符所有可能的条件查询(例如{criterion1} ),并调用on()的查询方法,通过实际SeqOption作为公认的答案描述的参数。


变更例中从ANORM文档,假设你有两个标准,但只是想你的查询,以便对国家代码,而不是在资本筛选:

SQL(
"""
select * from Country c 
join CountryLanguage l on l.CountryCode = c.Code 
where ({countryCode} is null or c.code = {countryCode})
  and ({capital} is null or c.capital = {capital});
"""
).on("countryCode" -> Some("FRA"), "capital" -> None)

这应该够了吧。



Answer 2:

简短的回答第一。 假如说你有含3列数据库中的表: nameemailpass 。 但是,从用户,你只得到了namepassword而不是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()
 }

做好以上,因为emailNone ,它会插入null在数据库中。 所以你的情况,您的所有10列,您可以在其中定义SQL上述声明,并通过Optionon() 如果他们中任何一个None ,那么它将把它作为null数据库。

虽然有可能是一个问题,如果有您的模式作为一个列上的约束NOT NULL 。 在这种情况下,你可以使用getOrElse对这些列asbelow:

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()

以下是关于如何发挥转换类型数据库类型领悟列表。 它可以在对象中找到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它需要它为空。


在的情况下, SELECT嗯,我不知道有任何ANORM功能,帮助这里的,但我想简单的字符串操作就足够:

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构建库。 要做到你想要什么,它也必须记住你的表的模式(即ATLEAST列名..)。 我不认为ANORM由尽一切



Answer 3:

ANORM似乎克利在您插入普通的旧SQL的前提下进行操作,而无需如类型安全或查询建筑物内的任何功能。 它可能不是动态查询的工具。 构建查询必须是字符串操作,最终,所以我会建议使用,这是否对你的库。 它应该是很容易的任何库集成,用于生成与ANORM SQL语句。

您可以动态地构造一个查询,传递查询字符串ANORM与就像一个图书馆jOOQ 。 作为奖励,你会得到许多数据库的支持。 jOOQ似乎是受欢迎的,但有可能是,你可以改用其他很多图书馆。 或更换ANORM完全,如果它是不适合你的项目。



文章来源: anorm dynamic filters