15

私は Scala の初心者で、巧妙に苦労しており、呼び出し元のメソッドにクエリの結果を返す方法がわかりません。

私は単純な UserDto を持っています

case class UserDto(val firstName:String,
  val lastName:String,
  val userName:String,
  val isAdmin:Boolean) {}

ユーザー テーブル オブジェクト

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

}

およびクエリ クラス

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
  }
}

データベースにクエリを実行して、ユーザー名に一致するユーザーを取得できますが、そのユーザーを返す方法を理解できる唯一の方法は、 の外側に var を作成することDatabase.forDataSource....{}です。

var を使用せずにresultDto直接返すより良い方法はありますか。

UserDtoまた、(t <- q)のために2番目を必要とするのではなく、理解のために最初から直接構築する方法もあります...

slick_2.10.0-M7、バージョン 0.11.1 を使用しています。

4

2 に答える 2

9

あなたqはクエリであり、結果のリストではありません。の存在はforeachその点で少し混乱するかもしれませんが、List結果を得るには、最初に行う必要がありますq.listmapそれはあなたになどのようなメソッドを与えますfoldLeft

の単一/最初の結果を取得する場合はOption、を使用しますq.firstOption。それができmapたら、結果の'Option [(...)]`に対して関数を実行して、タプルを目的のDTOに変換できます。

<>別の方法は、演算子を使用して結果タプルを特定のケースクラスに自動的にマップするカスタムマッピングを指定することです。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 _)
}
于 2012-11-02T17:28:54.627 に答える
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) }
  }

これは、 が である場合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
  }

それ以外の場合は、使用できるはずです

q foreach { 
   case (f, l, u, a) => return Some(UserDto(f, l, u, a))
}
return None

一般に、returnこのようなステートメントは避けるべきなので、qの型がより機能的なものを提供してくれることを願っています。

于 2012-10-27T05:57:29.217 に答える