2013-08-14 13 views
7

Sono molto nuovo sia per Scala che per Slick e nel tentativo di impararlo sto scrivendo una piccola applicazione che funziona con un semplice database.Scala Slick e tipi complessi nel mio database

La maggior parte della mia precedente esperienza proviene da .Net e Entity Framework, quindi mi chiedevo se mi piace in Entity Framework con l'attributo ComplexType se Slick mi consente di fare lo stesso.

Fondamentalmente una delle mie tabelle è una relazione 1-1 e per alcune di esse preferirei semplicemente creare un oggetto e usarlo come un tipo complesso. Ovviamente nel database ci sono solo colonne in più sul tavolo, ma mi chiedevo se Slick potesse mappare quelle colonne su un oggetto nella mia classe Table. Vedi l'esempio qui sotto.

Utilizzerò un esempio di voce Blog.

La mia classe principale che estende Table è BlogEntry e contiene il testo della voce. Quindi dì che desideravo in quella classe un'altra classe chiamata EntryDetails che contenesse il tempo di pubblicazione della voce e l'ora dell'ultimo aggiornamento.

Nel database tutti questi campi si troveranno nella stessa tabella, ma quando letti in esso sarà un oggetto contenente l'altro oggetto. È possibile con Slick?

+1

Sì, è possibile. È necessario [implementare un 'TypeMapper' personalizzato]] (http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and-types) per quello. (Scriverò una vera risposta più tardi.) – Carsten

+0

Impressionante grazie mille. Sì, quando lo farai, accetterò come risposta. Grazie mille per la veloce risposta. – twreid

+0

Hai risolto il tuo problema con TypeMapper? Hai ancora bisogno di un campione su come farlo? – dirceusemighini

risposta

5

Penso che questo risolve il problema

trait Mapping { 
    //Need to change JdbcDriver to the driver that you will use in your code (MySql, Postgres, etc) 

    import scala.slick.driver.JdbcDriver.profile.simple._ 

    // Models 
    case class EntryDetails(createDate: Option[DateTime] = None, updateDate: Option[DateTime] = None) 

    case class Entry(id: Int, text: String, details: EntryDetails) 

    //Implicit Joda Mappers for datetime columns 
    implicit def timestamp2dateTime = MappedColumnType.base[DateTime, Timestamp](
    dateTime => new Timestamp(dateTime.getMillis), 
    date => new DateTime(date)) 

    //Table mapping 
    class Entries(tag: Tag) extends Table[Entry](tag, "entry") { 
    def entryDetails = (createDate, updateDate) <>(EntryDetails.tupled, EntryDetails.unapply) 

    def * = (id, text, entryDetails) <>(Entry.tupled, Entry.unapply) 

    val id: Column[Int] = column[Int]("id") 
    val text: Column[String] = column[String]("text") 
    val createDate: Column[Option[DateTime]] = column[Option[DateTime]]("createDate") 
    val updateDate: Column[Option[DateTime]] = column[Option[DateTime]]("updateDate") 
    } 

    //Table query, used in slick 2.0 for querying a table 
    lazy val EntryTableQuery = TableQuery[Entries] 
} 

ho inserito tutto in un tratto di mappatura, per confezionare il codice per la risposta. Per quanto ho capito, vuoi mappare una tabella a due oggetti, uno dentro l'altro, questo può essere ottenuto creando un altro metodo di mappatura, qui chiamato entryDetails, che mappa le query della tabella nell'oggetto del modello EntryDetails. Quindi è possibile aggiungere questo metodo di mappatura alla mappatura dell'oggetto, il metodo *. Il metodo entryDetails sarà solo un altro parametro di quel metodo di mappatura.

+0

Dolce grazie! :) Questo ha fatto quello che stavo cercando grazie mille. – twreid

Problemi correlati