2013-01-15 76 views
0

假設這兩個簡單的查詢:如何通過WHERE子句條件參數化Scala查詢?

def findById(id: Long): Option[Account] = database.withSession { implicit s: Session => 
    val query = for (a <- Accounts if a.id === id) yield a.* 
    query.list.headOption 
} 

def findByUID(uid: String): Option[Account] = database.withSession { implicit s: Session => 
    val query = for (a <- Accounts if a.uid === uid) yield a.* 
    query.list.headOption 
} 

我想重寫它刪除重複的樣板,以這樣的:

def findBy(criteria: ??? => Boolean): Option[Account] = database.withSession { 
    implicit s: Session => 
    val query = for (a <- Accounts if criteria(a)) yield a.* 
    query.list.headOption 
} 

def findById(id: Long) = findBy(_.id === id) 

def findByUID(uid: Long) = findBy(_.uid === uid) 

我不知道如何去實現它有在理解中涉及的幾個隱式轉換我還沒有解開。更具體地說:findBy方法中??? => Boolean的類型是什麼?

編輯

這些帳戶和帳戶類:

case class Account(id: Option[Long], uid: String, nick: String) 

object Accounts extends Table[Account]("account") { 
    def id = column[Option[Long]]("id") 
    def uid = column[String]("uid") 
    def nick = column[String]("nick") 
    def * = id.? ~ uid ~ nick <> (Account, Account.unapply _) 
} 
+0

P租賃請參閱http://stackoverflow.com/questions/14501159/higher-order-functions-with-scala-slick-for-dry-goodness/16892497#16892497 – Sameer

回答

4

我有這樣的幫手錶:

abstract class MyTable[T](_schemaName: Option[String], _tableName: String) extends Table[T](_schemaName, _tableName) { 
    import scala.slick.lifted._ 
    def equalBy[B: BaseTypeMapper] 
    (proj:this.type => Column[B]):B => Query[this.type,T] = { (str:B) => 
    Query[this.type,T,this.type](this) where { x => proj(x) === str} } 

} 

現在你可以這樣做:

val q=someTable.equalBy(_.someColumn) 
q(someValue) 
+2

+1,很好的解決方案,但是,這是怎麼回事與createFinderBy有什麼不同? Slick和Foo.createFinderBy(_。whatever)內置的功能相同。 – virtualeyes

+0

不完全。 createFinder是不同的,因爲它創建了一個QueryTemplate,你可以在其中添加其他限制。我發明了這一個,正是爲了克服createFinder的這個限制。 – pedrofurla

+0

哦,我忘了在將一個內襯分成多行後刪除分號。 – pedrofurla