2014-11-22 140 views
1

目標是使用可選關鍵字和/或shopId過濾項目。使用Slick 2.1.0構建動態查詢

如果沒有定義它們,則應返回所有項目。

我的嘗試是

case class ItemSearchParameters(keywords: Option[String], shopId: Option[Long]) 

def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     val q = Items.query 
     if (params.keywords.isDefined) { 
      q.filter { i => 
      ((i.title like "%" + params.keywords + "%") 
      || (i.description like "%" + params.keywords + "%")) 
      } 
     } 
     if (params.shopId.isDefined) { 
      q.filter { i => 
      i.shopId === params.shopId 
      } 
     } 
     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

params.keywords或params.ShopId這個函數返回的所有項目。有人可以解釋什麼是錯的?


更新:第二次嘗試

def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     var q = Items.query 
     q = params.keywords.map{ k => q.filter(_.title like "%" + k + "%")} getOrElse q 
     q = params.keywords.map{ k => q.filter(_.description like "%" + k + "%")} getOrElse q 
     q = params.shopId.map{ sid => q.filter(_.shopId === sid)} getOrElse q 
     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

對於第二次嘗試該怎麼辦(標題或說明)如果關鍵字isDefined?


更新:如果關鍵字給出

回答

0
def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     var q = Items.query 

     q = params.keywords.map{ k => q.filter(
      i => (i.title like "%" + k + "%") 
       || (i.description like "%" + k + "%") 
     )} getOrElse q 

     q = params.shopId.map{ sid => q.filter(
      _.shopId === sid 
     )} getOrElse q 

     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

與MaybeFilter第三次嘗試不工作

case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) { 
    def filteredBy(op: Option[_])(f:(X) => Column[Option[Boolean]]) = { 
    op map { o => MaybeFilter(query.filter(f)) } getOrElse { this } 
    } 
} 


class ItemDAO extends Configuration { 

    implicit def maybeFilterConversor[X,Y](q:Query[X,Y,Seq]) = new MaybeFilter(q) 

    def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     val q = Items 
      .filteredBy(params.keywords){i => ((i.title like "%" + params.keywords + "%") 
      || (i.description like "%" + params.keywords + "%"))} 
      .filteredBy(params.shopId){_.shopId === params.shopId} 
      .query 
     Right(q.list) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 
} 

第三次嘗試返回空列表,我不知道這是最好的答案,因爲var q

0

據我瞭解你co正確的,你想通過可選字段進行過濾。 你的第二次嘗試更接近現實,第一次有不正確的匹配,你比較選項字段和非選項。你已經回答了你自己的答案,而我寫這篇迴應:)

我想推薦你這個MaybeFilter https://gist.github.com/cvogt/9193220

或者這裏修改的版本:https://github.com/neowinx/hello-slick-2.1-dynamic-filter/blob/master/src/main/scala/HelloSlick.scala#L3-L7

也許這可以幫助您以更通用的方式解決您的問題。

+0

謝謝,我只是試圖使用它,但我無法使它與標題或關鍵字一起工作。請參閱我的問題中的第三次嘗試:) – arsenik 2014-11-22 14:09:01

+0

哦,我明白了,必須查看生成的查詢。) – DaunnC 2014-11-22 18:26:54