【问题标题】:Select single row based on Id in Slick根据 Slick 中的 Id 选择单行
【发布时间】:2013-05-03 21:33:54
【问题描述】:

我想根据 Id 从用户那里查询一行。我有以下虚拟代码

case class User(
    id: Option[Int], 
    name: String
}

object Users extends Table[User]("user") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = id ~ name <>(User, User.unapply _)

  def findById(userId: Int)(implicit session: Session): Option[User] = {
    val user = this.map { e => e }.where(u => u.id === userId).take(1)
    val usrList = user.list
    if (usrList.isEmpty) None
    else Some(usrList(0))
  }
}

在我看来,findById 是查询单个列的过度杀伤力,因为 Id 是标准主键。有谁知道更好的方法?请注意,我正在使用 Play! 2.1.0

【问题讨论】:

标签: scala slick scalaquery


【解决方案1】:

在 Slick 3.* 中使用headOption 方法:

  def findById(userId: Int): Future[Option[User]] ={
    db.run(Users.filter(_.id === userId).result.headOption)
  }

【讨论】:

  • 有没有办法做一些类似于 LINQ 的事情,其中​​有一个 .First() 方法和一个 .Single() 方法? .First 只返回第一个“行”,如果结果集中有超过 1 行,.Single 会抛出异常。
【解决方案2】:

您可以通过从 list 切换到 firstOption 来从函数中删除两行。看起来像这样:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val user = this.map { e => e }.where(u => u.id === userId).take(1)
  user.firstOption
}

我相信你也会这样查询:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val query = for{
    u <- Users if u.id === userId
  } yield u
  query.firstOption
}

【讨论】:

【解决方案3】:

firstOption 是一条路,是的。

拥有

  val users: TableQuery[Users] = TableQuery[Users]

我们可以写

def get(id: Int): Option[User] = users.filter { _.id === id }.firstOption

【讨论】:

    【解决方案4】:

    一个简短的答案。

      `def findById(userId: Int)(implicit session: Session): Option[User] = {
         User.filter(_.id === userId).firstOption
            }`
    

    【讨论】:

      【解决方案5】:
      case class User(
          id: Option[Int], 
          name: String
      }
      
      object Users extends Table[User]("user") {
        def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
        def name = column[String]("name")
        def * = id.? ~ name <>(User.apply _, User.unapply _)
        // .? in the above line for Option[]
      
        val byId = createFinderBy(_.id)
        def findById(id: Int)(implicit session: Session): Option[User] = user.byId(id).firstOption
      

      【讨论】:

        猜你喜欢
        • 2012-09-02
        • 1970-01-01
        • 1970-01-01
        • 2021-03-29
        • 2017-06-04
        • 2018-12-06
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多