我有一个查询,我有条件地根据计数和偏移参数的存在与否进行增强。
val retrieveCustomer: (Option[String], Option[Int], Option[Int]) => List[Customer] = { ( customerId : Option[String], count : Option[Int], offset : Option[Int] ) =>
val initialQ: Query[CustomerTable.type, Customer] = customerId.map( c => CustomerTable.where(_.id === c) ).getOrElse( CustomerTable.map { c => c } )
val qPlusOffset = offset.map ( offset => initialQ.drop(offset) ).getOrElse(initialQ)
val qoPlusLimit = count.map( count => qPlusOffset.take(count) ).getOrElse(qPlusOffset)
DBGlobal.db.withTransaction { qoPlusLimit.list }
}
我很好奇,与这种方法相比,是否有更简洁的方式来编写这个。
祈祷告诉。
答案 0 :(得分:2)
写这个是什么意思?
val retrieveCustomer: (Option[String], Option[Int], Option[Int]) => List[Customer] = { ( customerId : Option[String], count : Option[Int], offset : Option[Int] )
当你可以写这样的东西时:
def getCustomer(id: String, count: Option[Int], offset: Option[Int]): List[Customer]
这显然更简洁,虽然可能与你所追求的简洁无关。我倾向于对for {...}块中的每个操作使用Either Right投影,“失败”执行基本或非完全精炼查询的左结果,并且成功执行完全删除+权限结果
def getCustomer(id: String, count: Option[Int], offset: Option[Int]): List[Customer] = {
val base = Customers.createFinder(_.id)
val q = for{
cust <- base(id) toRight( List[Customer]() )
dropped <- cust.drop(offset) toRight(cust)
taken <- dropped.take(count) toRight(dropped)
} yield taken
DBGlobal.db.withTransaction { q.list map { _.fold(_,_) } }
}
不太可能这个编译;-),但一般原则是通过左/右查询结果来回转,它们都返回一个客户列表。
注意:我倾向于以复数形式的case类命名mapper伴侣对象,所以在这种情况下,我使用Customers而不是CustomerTable。另外,Customers.createFinder(_.id)
去了:
for{
id <- Parameters[String]
c <- Customers if c.id is id
} yield c
懒惰地为底层DBMS生成有效的预准备语句。
你有什么工作当然,对于一次性案件看起来很好。就个人而言,我正在挖掘{} +正确的投射,可以拥有你的蛋糕并吃掉它 - 即获得两个失败点左结果和成功的正确结果,而不是{...}通过选项,这只会产生一个成功的事件,根本不提供关于哪个步骤实际出错的信息。
答案 1 :(得分:0)
这是一个班轮。
val qFinal = initialQ.drop(offset.getOrElse(0)).take(count.getOrElse(Int.MaxValue))