scala slick查询返回值

Dou*_*son 15 scala slick

我是Scala的新手,一直在苦苦挣扎,无法看到如何将查询结果返回给调用方法

我有一个简单的UserDto

case class UserDto(val firstName:String,
  val lastName:String,
  val userName:String,
  val isAdmin:Boolean) {}
Run Code Online (Sandbox Code Playgroud)

用户表对象

object User extends Table[(String, String, String, Boolean)]("USER") {

  def firstName = column[String]("FIRST_NAME")
  def lastName = column[String]("LAST_NAME")
  def userName = column[String]("USER_NAME")
  def admin = column[Boolean]("IS_ADMIN")

  def * = firstName ~ lastName ~ userName ~ admin

}
Run Code Online (Sandbox Code Playgroud)

和查询类

class UserQuerySlickImpl(dataSource:DataSource) {

  def getResults(userName:String):Option[UserDto] = {
    var resultDto:Option[UserDto] = None

    Database.forDataSource(dataSource) withSession {
      val q = for {u <- User if u.userName is userName}
      yield (u.firstName, u.lastName, u.userName, u.admin)

      for (t <- q) {
        t match {
          case (f:String, l:String, u:String, a:Boolean) => 
            resultDto = Some(new UserDto(f, l, u, a))
        }
      }
    }
    resultDto
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以查询数据库并获取与用户名匹配的用户,但我能想出如何返回该用户的唯一方法是创建一个var之外的Database.forDataSource....{}.

有没有更好的方法不使用var但resultDto直接返回.

还有一种方法可以UserDto直接从第一个构造直到理解,而不是需要第二个(t < - q)......

我使用的是slick_2.10.0-M7,版本0.11.1.

Aar*_*rup 9

我还没玩过Slick但是如果它是合理的(我的意思是与Scala约定一致)你应该能够做类似的事情

def getResults(userName:String):Option[UserDto] =
  Database.forDataSource(dataSource) withSession {
    val q = for {u <- User if u.userName is userName}
      yield (u.firstName, u.lastName, u.userName, u.admin)

    q.firstOption map { case (f, l, u, a) => UserDto(f, l, u, a) }
  }
Run Code Online (Sandbox Code Playgroud)

这就是,如果你会做什么q是一个List[(String, String, String, Boolean)].

清理一下,你可以写

def getResults(userName:String):Option[UserDto] =
  Database.forDataSource(dataSource) withSession {
    (for (u <- User if u.userName is userName)
      yield UserDto(u.firstName, u.lastName, u.userName, u.admin)).firstOption
  }
Run Code Online (Sandbox Code Playgroud)

否则,你应该可以使用

q foreach { 
   case (f, l, u, a) => return Some(UserDto(f, l, u, a))
}
return None
Run Code Online (Sandbox Code Playgroud)

一般来说,return应该避免使用像这样的语句,所以希望q类型可以为你提供更多功能.


eri*_*sei 9

q是查询,而不是结果列表.foreach在这方面存在可能有点混乱,但要获得List结果,您需要先做q.list.这就给了你喜欢的方法mapfoldLeft等.

如果你想获得单个/第一个结果Option,请使用q.firstOption.一旦你有了这个,你就可以map对结果'Option [(...)]`进行操作,将元组转换为所需的DTO.

另一种方法是指定一个自定义映射,通过使用<>运算符自动将结果元组映射到某个case类,请参阅http://slick.typesafe.com/doc/0.11.2/lifted-embedding.html#tables:

case class User(id: Option[Int], first: String, last: String) 

object Users extends Table[User]("users") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def first = column[String]("first")
  def last = column[String]("last")
  def * = id.? ~ first ~ last <> (User, User.unapply _)
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.:)文档对我来说有点拼凑.我通过查看我链接的文档,邮件列表,StackOverflow和https://github.com/slick/slick-examples来拼凑一些东西.`firstOption`来源于源代码中的问题.查看ScalaQuery的东西(例如GitHub上使用它的项目)也有帮助.然后是[亚当·麦克勒的这本电子书](https://mackler.org/LearningSlick)看起来非常有用. (2认同)