Slick 是否有办法采用动态查询大小?

Does Slick have a way of taking a dynamic query size?

我正在尝试使用 slick 进行查询,其中一个参数是查询的元素数量 returns(通常您通过将参数传递给“.take”来实现)。但是,我希望此参数是可选的(寻找类似 .maybeFilter 的命令,但寻找 .take),我一直在寻找,但似乎无法找到它。有人有什么建议吗?

我建议捕获您想要 运行 的主要查询,然后使用常规 Option 方法应用 take。类似于:

def query(taking: Option[Int]) = {
  val baseQuery = table.filter(...).map(...)
  taking.map(size => baseQuery.take(size)) getOrElse baseQuery
}

如果您经常这样做,将行为包装到自己的 class 中可能很有意义,例如 MaybeFilter.

动态查询过滤器 slick-doc

1.first方式(所有动态过滤器都是'and')

def selectByHotelIdAndStartTimeAndEndTimeAndPerpageAndOffset(
      hotelId: Option[String],
      caseTimeFilter: Option[CaseTimeFilter[Timestamp]],
      perPage: Int,
      offset: Int
  ): Future[Seq[GoodsOrderMstinfoTRow]] =
    db.run(
      tableQ
        .filter { goodsOrderMstinfoT: GoodsOrderMstinfoT =>
          List(
            hotelId.map(goodsOrderMstinfoT.hotelid === _),
            caseTimeFilter.map(t => goodsOrderMstinfoT.createTime between (t.start, t.end))
          ).collect({ case Some(repBoolean) => repBoolean })
            .reduceLeftOption(_ && _)
            .getOrElse(true: Rep[Boolean])
        }
        .drop(offset)
        .take(perPage)
        .sortBy(_.gomtId.desc)
        .result
    )

2.second 方式

def selectCountByHotelIdAndStartTimeAndEndTime(
      optionHotelId: Option[String],
      rmiSerialno: Option[String],
      caseTimeFilter: Option[CaseTimeFilter[Timestamp]]
  ): Future[Int] =
    db.run(
      tableQ
        .filter { RoomReviewT: RoomReviewT =>
          optionHotelId match {
            case Some(hotelid) => RoomReviewT.hotelid === hotelid
            case None          => true: Rep[Boolean]
          }
        }
        .filter { RoomReviewT: RoomReviewT =>
          rmiSerialno match {
            case Some(rmiSerialNo) => RoomReviewT.rmiSerialno === rmiSerialNo
            case None              => true: Rep[Boolean]
          }
        }
        .filter { RoomReviewT: RoomReviewT =>
          caseTimeFilter match {
            case Some(timeFilter) =>
              RoomReviewT.createTime between (timeFilter.start, timeFilter.end)
            case None => true: Rep[Boolean]
          }
        }
        .length
        .result
    )

`