我是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.
我还没玩过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
类型可以为你提供更多功能.
您q
是查询,而不是结果列表.foreach
在这方面存在可能有点混乱,但要获得List
结果,您需要先做q.list
.这就给了你喜欢的方法map
和foldLeft
等.
如果你想获得单个/第一个结果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)
归档时间: |
|
查看次数: |
10585 次 |
最近记录: |