2013-07-18 14 views
8

Die Auswahl einer einzelnen Zeile nach ID sollte eine einfache Sache sein, aber ich habe ein wenig Mühe herauszufinden, wie man dies auf mein Objekt abbildet.Slick Zeile nach ID auswählen

Ich fand this question, die für das gleiche Ding sucht, aber die gegebene Antwort funktioniert nicht für mich.

Derzeit habe ich das, das funktioniert, aber es scheint nicht so elegant, wie es sein sollte.

def getSingle(id: Long):Option[Category] = withSession{implicit session => 
(for{cat <- Category if cat.id === id} yield cat).list.headOption 
//remove the .list.headOption and the function will return a WrappingQuery 
} 

Ich fühle mich dann eine Liste bekommen headOption nehmen nur sperrig und unnötig. Ich muss etwas verpassen.

Wenn es hilft, ist hier mehr meiner Kategorie Code

case class Category(
    id: Long = 0L, 
    name: String 
) 
object Category extends Table[Category]("categories"){ 

    def name = column[String]("name", O.NotNull) 
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc) 

    def * = id ~ name <> (Category.apply _, Category.unapply _) 

    ... 
} 

Gibt es eine einfachere Möglichkeit, nur eine Option [T] von einer ID erhalten Slick mit?

Lösung Es gab ein Treiberproblem. Ich konnte nicht .firstOption verwenden, aber auf mysql jdbc 5.1.25 aktualisiert und alles ist gut!

Antwort

9

Sie können dies tun:

def getSingle(id: Long):Option[Category] = withSession{implicit session => 
Query(Category).where(_.id === id).firstOption 
} 

Wenn Sie diese Abfrage verwenden oft dann sollten Sie QueryTemplate betrachten:

val byId = t.createFinderBy(t => t.id)

Dies erstellt ein vorkompiliertes vorbereitet Erklärung, dass Sie von Ihrer Methode verwenden können

def getSingle(id: Long):Option[Category] = byId(id).firstOption

+0

Wenn ich die erste Lösung, die Sie veröffentlicht habe, bekomme ich' Fehler in SQL-Syntax in der Nähe' OPTION SQL_SELECT_LIMIT = DEFAULT'' – kingdamian42

+3

Könnte ein Treiberproblem sein. Werfen Sie einen Blick auf http://stackoverflow.com/questions/15113707/error-code-1064-sql-state-42000-you-have-an-error-in-your-sql-syntax – Nilanjan

+2

Auf "mysql" aktualisiert % "mysql-connector-java"% "5.1.25" '. Funktioniert super, danke! – kingdamian42

3

Erstens können Sie versuchen, ist entzuckert Version des gleichen Code zu verwenden:

Category.filter{ _.id === id }.list.headOption 

Es sieht viel sauberer.

Auch Sie können firstOption Methode verwenden:

Category.filter{ _.id === id }.firstOption 
+0

Oder sogar ".first", wenn Sie sicher sind, dass Ihre Abfrage ein Objekt zurückgibt. Und ist es nicht 'Query (Category) ...'? –

+0

@alno Ich hatte eigentlich schon auf die Filterversion gewechselt und habe meinen Code hier einfach nicht aktualisiert. Aber die Verwendung von 'Category.filter (_. Id === id) .firstOption' gibt mir' type mismatch; found: Option [scala.slick.lifted.NothingContainer # TableNothing] benötigt: Option [models.Category] 'weshalb ich zu der list.headOption gewechselt habe. – kingdamian42

+0

Nur getestet - ich bekomme Option [scala.slick.lifted.NothingContainer # TableNothing] in beiden Varianten, Wrapping-Tabelle in Query (Category) hilft. – alno

0

ich glatt 1.0.1 mit Play 2.2.1 und die folgenden Werke für mich bin mit.

val byId = createFinderBy(_.id) 

Dann rufen Sie es von einer Methode.

def findById(id: Int): Option[Category] = DB.withSession { implicit session => 
    Category.byId(id).firstOption 
    } 

Bitte beachten Sie, dass die DB.withSession eine Methode aus dem play-Framework ist.

Wenn Sie nicht Play verwenden, wäre die Methode wie folgt.

def findById(id: Int)(implicit session: Session): Option[Category] = { 
    Category.byId(id).firstOption 
    } 
Verwandte Themen