2013-07-18 10 views
8

Selezionare una singola riga con id dovrebbe essere una cosa semplice da fare, tuttavia ho un po 'di problemi a capire come mapparlo al mio oggetto.Chiazza la riga di selezione per id

Ho trovato this question che sta cercando la stessa cosa ma la risposta data non funziona per me.

Attualmente ho questo che funziona, ma non sembra elegante come dovrebbe essere.

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 
} 

mi sento ottenere una lista poi prendendo headOption è solo ingombrante e inutile. Devo mancare qualcosa.

Se serve, qui è più del mio codice categoria

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

    ... 
} 

C'è un modo più semplice per ottenere solo un opzione [T] da un ID utilizzando Slick?

Soluzione Si è verificato un problema con il driver. Non ho potuto usare .firstOption ma aggiornato a mysql jdbc 5.1.25 e tutto va bene!

risposta

9

Si può fare questo:

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

Se si utilizza questa query abbastanza spesso, allora si dovrebbe prendere in considerazione QueryTemplate:

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

Questo creerà un preparato precompilato dichiarazione che è possibile utilizzare il metodo da

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

+0

Se utilizzo la prima soluzione che hai postato ottengo' errore nella sintassi SQL vicino' OPTION SQL_SELECT_LIMIT = DEFAULT'' – kingdamian42

+3

Potrebbe esserci un problema con il driver. Dai un'occhiata a http://stackoverflow.com/questions/15113707/error-code-1064-sql-state-42000-you-ha-err-inor-in-your-sql-syntax – Nilanjan

+2

Aggiornato a '" mysql " % "mysql-connector-java"% "5.1.25" '. Funziona alla grande, grazie! – kingdamian42

3

In primo luogo, si può provare è quello di utilizzare la versione Dezuccherato dello stesso codice:

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

Sembra molto più pulito.

Inoltre è possibile utilizzare il metodo firstOption:

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

O anche ".first" se si è sicuri che la query restituisce un oggetto. E non è 'Query (Category) ...'? –

+0

@alno In realtà avevo già cambiato la versione del filtro e non ho aggiornato il mio codice qui. Ma l'utilizzo di 'Category.filter (_. Id === id) .firstOption' mi dà la mancata corrispondenza di tipo'; trovato: Opzione [scala.slick.lifted.NothingContainer # TableNothing] richiesta: Opzione [models.Category] 'che è il motivo per cui sono passato a list.headOption in primo luogo. – kingdamian42

+0

Appena testato - Ottengo Option [scala.slick.lifted.NothingContainer # TableNothing] in entrambe le varianti, la tabella di wrapping in Query (Category) aiuta. – alno

0

Sto usando chiazza di petrolio 1.0.1 con Play 2.2.1 e le seguenti opere per me.

val byId = createFinderBy(_.id) 

Quindi chiamarlo da un metodo.

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

Nota: DB.withSession è un metodo del framework di gioco.

Se non si utilizza il gioco, il metodo sarebbe qualcosa di simile in basso.

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