2013-07-18 19 views
8

Wybór jednego wiersza za pomocą id powinien być prostą rzeczą do zrobienia, ale mam trochę problemów z ustaleniem, jak zmapować to do mojego obiektu.Slick select select by id

Znalazłem this question, który szuka tej samej rzeczy, ale udzielona odpowiedź nie działa dla mnie.

Obecnie mam to, co działa, ale nie wydaje się tak eleganckie, jak powinno być.

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 
} 

czuję się coraz listę następnie biorąc headOption tylko nieporęczne i niepotrzebne. Muszę czegoś przegapić.

Jeśli to nie pomaga, tutaj jest bardziej mojego kodu Kategoria

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 _) 

    ... 
} 

Czy istnieje prostszy sposób, aby po prostu opcję [T] z wykorzystaniem ID Slick?

Rozwiązanie Wystąpił błąd sterownika. Nie mogłem użyć .firstOption, ale zaktualizowałem do mysql jdbc 5.1.25 i wszystko jest dobrze!

Odpowiedz

9

Można to zrobić:

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

Jeśli używasz tej kwerendy dość często to należy rozważyć QueryTemplate:

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

Spowoduje to utworzenie prekompilowanego pliku oświadczenie, że można skorzystać z metody

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

+0

Jeśli używam pierwszego opublikowanego przez ciebie rozwiązania, otrzymuję komunikat" błąd w składni SQL w pobliżu "OPCJA SQL_SELECT_LIMIT = DEFAULT'' – kingdamian42

+3

Może to być problem ze sterownikiem. Spójrz na http://stackoverflow.com/questions/15113707/error-code-1064-sql-state-42000-you-have-an-error-in-your-sql-syntax – Nilanjan

+2

Zaktualizowano do '" mysql " % "mysql-connector-java"% "5.1.25" '. Działa świetnie, dzięki! – kingdamian42

3

Po pierwsze, można spróbować jest użycie odcukrzona wersję tego samego kodu:

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

wygląda znacznie czystsze.

Również można użyć metody firstOption:

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

Lub nawet ".pierwszy", jeśli masz pewność, że zapytanie zwróci obiekt. I czy to nie jest "Zapytanie (kategoria) ..."? –

+0

@alno Już faktycznie przełączyłem się na wersję filtra i po prostu nie zaktualizowałem tutaj mojego kodu. Ale użycie 'Category.filter (_. Id === id) .firstOption' daje mi' niedopasowanie typu; found: Option [scala.slick.lifted.NothingContainer # TableNothing] required: Option [models.Kategoria] 'i dlatego przełączyłem się na list.headOption w pierwszej kolejności. – kingdamian42

+0

Po prostu przetestowane - otrzymuję Option [scala.slick.lifted.NothingContainer # TableNothing] w obu wariantach, pomaga zawijanie tabeli w Zapytaniu (Kategoria). – alno

0

Używam zręczny 1.0.1 z luzem 2.2.1 oraz następujące prace dla mnie.

val byId = createFinderBy(_.id) 

Następnie wywołaj to za pomocą metody.

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

Proszę zauważyć, że DB.withSession jest metodą ze schematu gry.

Jeśli nie korzystasz z Play, metoda będzie podobna do poniższej.